腾讯 PB 级大数据计算如何做到秒级?
天穹 SuperSQL 是騰訊自研,基于統(tǒng)一的 SQL 語(yǔ)言模型,面向機(jī)器學(xué)習(xí)智能調(diào)優(yōu),提供虛擬化數(shù)據(jù)和開(kāi)放式計(jì)算引擎的大數(shù)據(jù)智能融合平臺(tái)。在開(kāi)放融合的 Data Cloud 上,業(yè)務(wù)方可以消費(fèi)完整的數(shù)據(jù)生命周期,從采集-存儲(chǔ)-計(jì)算-分析-洞察。還能夠滿足位于不同數(shù)據(jù)中心、不同類(lèi)型數(shù)據(jù)源的數(shù)據(jù)聯(lián)合分析/即時(shí)查詢的需求。
Presto 在騰訊天穹 SuperSQL 大數(shù)據(jù)生態(tài)中,定位為實(shí)現(xiàn)秒級(jí)大數(shù)據(jù)計(jì)算的核心服務(wù)。主要面向即席查詢、交互式分析等用戶場(chǎng)景。Presto 服務(wù)了騰訊內(nèi)部的不同業(yè)務(wù)場(chǎng)景,包括微信支付、QQ、游戲等關(guān)鍵業(yè)務(wù)。日均處理數(shù)據(jù)量 PB 級(jí),P90 查詢耗時(shí)為 50s,全面提升各業(yè)務(wù)數(shù)據(jù)實(shí)時(shí)分析性能,有效助力業(yè)務(wù)增長(zhǎng)。本篇文章將揭秘騰訊大數(shù)據(jù)在 Presto 上的核心工作,包括易用性、穩(wěn)定性、性能,以及未來(lái)的主要方向等方面。
1 天穹 Presto 整體架構(gòu)
天穹 Presto 作為天穹 SuperSQL 的主要執(zhí)行引擎之一,主要承擔(dān)著加速用戶 SQL 執(zhí)行速度的角色。SuperSQL 通過(guò)智能路由(RBO/CBO/HBO)的方式,智能篩選出合適的 SQL 并分發(fā)給 Presto 執(zhí)行,以加速 SQL 計(jì)算。另外,如果 Presto 執(zhí)行失敗,SuperSQL 也能自動(dòng) Failover 到 Hive 或 Spark 重新執(zhí)行,以確保用戶 SQL 能順利執(zhí)行完成,而整個(gè)過(guò)程對(duì)用戶透明、無(wú)感知。
關(guān)于天穹 SuperSQL 的介紹,可以查看歷史文章:「解耦」方能「專(zhuān)注」——騰訊天穹 SuperSQL 跨引擎計(jì)算揭秘
天穹 Presto 采用了 on K8s 容器化部署的方式,具備自動(dòng)化運(yùn)維、彈性伸縮等云原生能力。同時(shí)支持為不同的業(yè)務(wù)獨(dú)立部署專(zhuān)屬的 Presto 集群,以避免造成不同集群負(fù)載的相互影響。
得益于 Presto 的多數(shù)據(jù)源訪問(wèn)能力,天穹 Presto 支持對(duì)接了 Hive、Iceberg、MySQL 等數(shù)據(jù)源,且為了更好地支持內(nèi)部的業(yè)務(wù),我們也擴(kuò)展開(kāi)發(fā)了內(nèi)部的 TDW Connnector,支持訪問(wèn)騰訊內(nèi)部的數(shù)據(jù)倉(cāng)庫(kù)數(shù)據(jù)(TDW,Tencent distributed Data Warehouse)。同時(shí)天穹 Presto 使用了 Alluxio 作為數(shù)據(jù)源(Hive 表、Iceberg 表)的緩存層,用于加速熱點(diǎn)數(shù)據(jù)的訪問(wèn),可有效提升 Presto 查詢的效率。
2 易用性增強(qiáng)
2.1 Hive 語(yǔ)法兼容
由于部分用戶習(xí)慣于使用 Hive 的語(yǔ)法,而 Presto 自身的語(yǔ)法語(yǔ)義與 Hive 相比又有些不同,因此天穹 Presto 在引擎?zhèn)茸隽思嫒莶糠?Hive 語(yǔ)法語(yǔ)義的工作,主要包括:數(shù)值除法、數(shù)組下標(biāo)取值、Hive UDF 支持、Mapjoin Hint、隱式轉(zhuǎn)換等。
對(duì)于 Mapjoin Hint,其實(shí)是對(duì)應(yīng)于 Presto 中的 Broadcast Join,用戶通過(guò) Mapjoin Hint 來(lái)指定多表 Join 中的需要 Broadcast(廣播)的表,以此提升查詢的性能,適用于大小表 Join 的場(chǎng)景。目前已支持在 Inner Join 和 Left Join 中使用 Mapjoin Hint。
--?Presto采用Broadcast?Join,Broadcast的表為test2 select?t1.b,?/*+mapjoin(t2)*/?t2.b2?from?test1?t1?join?test2?t2?on?t1.a?=?t2.a2;--?Presto采用Broadcast?Join,Broadcast的表為test1、test3 select?t1.b,?/*+mapjoin(t1,t3)*/?t2.b2,?t3,b3?from?test1?t1?join?test2?t2?on?t1.a?=?t2.a2?join?test3?t3?on?t1.a=t3.a3;由于原生 Presto 不支持?jǐn)?shù)值類(lèi)型與字符串之間的隱式轉(zhuǎn)換,為了兼容部分習(xí)慣于使用隱式轉(zhuǎn)換的用戶,天穹 Presto 在引擎?zhèn)茸隽嗽鰪?qiáng),以支持類(lèi)似于 Hive 語(yǔ)法中隱式轉(zhuǎn)換的功能。
天穹 Presto 隱式轉(zhuǎn)換規(guī)則表如下所示:(綠色表示支持從 Source Type 到 Target Type 的隱式轉(zhuǎn)換,其余空白格表示不支持類(lèi)型之間的隱式轉(zhuǎn)換)。
2.2 Query 運(yùn)行信息持久化
Presto 的 Event Listener 提供了相關(guān)的接口,可以在查詢執(zhí)行完成后獲取不同緯度的 Metrics 信息,比如查詢執(zhí)行期間各階段的耗時(shí)、處理的數(shù)據(jù)量、內(nèi)存/CPU 消耗、Stage/Task/Operator 統(tǒng)計(jì)信息等,天穹 Presto 擴(kuò)展實(shí)現(xiàn)了 Event Listener 接口,將這些 Query Metrics 信息持久化到本地磁盤(pán)以及消息組件中,用于后續(xù)的問(wèn)題定位、運(yùn)維審計(jì)、資源統(tǒng)計(jì)、HBO 等。
2.3 Iceberg Connector 功能增強(qiáng)
騰訊天穹實(shí)時(shí)數(shù)倉(cāng)-數(shù)據(jù)湖分析系統(tǒng) DLA 使用了 Iceberg 作為表的數(shù)據(jù)組織格式,用戶數(shù)據(jù)入湖后,可以通過(guò) Presto Iceberg Connector 獲得秒級(jí)的查詢體驗(yàn)。天穹 Presto 也對(duì) Iceberg Connector 做了一系列的功能增強(qiáng),包括 ORC 存儲(chǔ)格式支持(PR-16391)、Timestamp With Time Zone 類(lèi)型支持、Alluxio Local Cache 支持(PR-16942)、并發(fā)寫(xiě)入(PR-16983)、Bugfix(PR-16959、PR-16968 )等,大部分的特性或問(wèn)題修復(fù)也已貢獻(xiàn)到了 PrestoDB 社區(qū)。
3 穩(wěn)定性提升
3.1 JVM 調(diào)優(yōu)
Presto 在天穹上線運(yùn)行的過(guò)程中,遇到過(guò) Worker Full GC 停頓時(shí)間過(guò)長(zhǎng)的問(wèn)題,為此天穹 Presto 將 JDK 版本升級(jí)到了 11(參考社區(qū) issue 14873),并對(duì) JVM 參數(shù)做了持續(xù)的調(diào)優(yōu),比如適當(dāng)增大-XX:GCLockerRetryAllocationCount 參數(shù)的值(默認(rèn)為 2),以增加 Full GC 的概率盡量避免 OOM 的情況發(fā)生。目前在堆內(nèi)存為 180GB、CPU 96 核的硬件條件下,天穹 Presto Worker Full GC 的平均耗時(shí)從數(shù)十秒降低到了十秒以內(nèi),停頓時(shí)間大幅下降。
3.2 Full GC Query Killer
Presto 的查詢內(nèi)存使用統(tǒng)計(jì)是相對(duì)比較粗粒度的,這可能會(huì)導(dǎo)致原生的 LowMemoryKillerPolicy 在某些情況下不能正確地 Kill 查詢,天穹 Presto 在線上運(yùn)行的過(guò)程中就遇到過(guò)類(lèi)似的情況:Worker 堆內(nèi)存已經(jīng)接近用滿了,但是 Presto 自身的 Memory Pools 顯示還有較多的空閑內(nèi)存,導(dǎo)致無(wú)法及時(shí)觸發(fā) LowMemoryKillerPolicy。為了盡量避免這種情況,天穹 Presto 開(kāi)發(fā)了 Full GC Query Killer,該策略可以在 Worker Full GC 之后,如果 Worker 堆內(nèi)存使用還是處于高值,則 Kill 掉在該 Worker 上使用最多內(nèi)存的查詢。需要注意的是,該策略是在應(yīng)用程序?qū)用鎴?zhí)行的,如果 Worker 不斷地 Full GC 乃至最后 OOM,那么 Full GC Query Killer 可能也得不到響應(yīng),這時(shí)候還是需要通過(guò)其他手段分析定位出 Full GC 或 OOM 的原因,以徹底解決問(wèn)題。
Full GC Query Killer 相關(guān)的代碼也將在近期貢獻(xiàn)至 PrestoDB 社區(qū),歡迎大家關(guān)注。
3.3 大文件 ORC 統(tǒng)計(jì)信息讀取優(yōu)化
Presto 在讀取 ORC 文件時(shí),會(huì)先讀取文件的 Stripe 統(tǒng)計(jì)信息,用于優(yōu)化 ORC 的數(shù)據(jù)讀取,但是如果 ORC 文件比較大,同時(shí)文件數(shù)量又比較多的情況下,StripeStatistics 對(duì)象會(huì)占用較多的 Worker 堆內(nèi)存,這些內(nèi)存對(duì)象不斷累積最終極易造成 OOM。天穹 Presto 采用了以下的方案來(lái)盡量避免這個(gè)問(wèn)題:對(duì)于來(lái)自同一個(gè) ORC 大文件的 Splits,避免重復(fù)讀取文件的 Stripe 統(tǒng)計(jì)信息。
SplitFilerOperator 會(huì)先讀取一次 ORC 文件的 Stripe 統(tǒng)計(jì)信息,生成新的 ORC Splits,新的 Splits 包含了利用 Stripe 統(tǒng)計(jì)信息過(guò)濾優(yōu)化后的數(shù)據(jù)讀取地址,后續(xù) ORC Splits 分發(fā)至 Worker 中執(zhí)行時(shí),無(wú)需再讀取 Stripe 統(tǒng)計(jì)信息,直接讀取數(shù)據(jù)即可。
天穹內(nèi)部環(huán)境測(cè)試結(jié)果顯示該方案能減少50%左右的 StripeStatistics 對(duì)象內(nèi)存占用,原先造成 OOM 的 ORC 查詢,采用新方案的實(shí)現(xiàn)后也可以正常執(zhí)行完成,目前正在上線生產(chǎn)環(huán)境中。
4 性能優(yōu)化
4.1 Presto on Alluxio
天穹 Presto on Alluxio 主要有兩種部署模式:Presto on Alluxio Cluster 以及 Presto Alluxio Local Cache,前者是比較通用的一種部署方式,但是需要額外維護(hù)一套 Alluxio 集群,Presto 可以與 Alluxio 集群共部署或者分離部署,共部署的方式能有效提高本地讀緩存的命中率,提升查詢效率。Presto Alluxio Local Cache 則是更輕量的部署模式,無(wú)需單獨(dú)的 Alluxio 集群,數(shù)據(jù)緩存在 Presto Worker 側(cè),運(yùn)維方便,缺點(diǎn)是 Presto Worker 動(dòng)態(tài)擴(kuò)縮容的場(chǎng)景下緩存會(huì)失效,目前 PrestoDB 和 Alluxio 社區(qū)也在持續(xù)推進(jìn) Local Cache 的方案,相信后續(xù)會(huì)越來(lái)越完善。
天穹 Presto 根據(jù)各業(yè)務(wù)的場(chǎng)景需求,對(duì) on Alluxio 的方案做了以下增強(qiáng),提高了易用性和可擴(kuò)展性:
支持針對(duì)不同的 Connector 配置不同的 Alluxio 路由策略,比如 Hive Connector 和 Iceberg Connector;
在 Presto 側(cè),新增 Alluxio 白名單機(jī)制,支持配置訪問(wèn)緩存在不同 Alluxio 集群下的庫(kù)表數(shù)據(jù);
在路由前檢測(cè) Alluxio 服務(wù)的狀態(tài)可用性,當(dāng) Alluxio 服務(wù)不可用時(shí)自動(dòng) Failover 至 HDFS;
白名單配置參數(shù)說(shuō)明如下:
"clusterUrl":Alluxio 集群的 url 地址,不同的集群可以配置不同的 url。
"tables":Presto 查詢中涉及到的庫(kù)表,如果已經(jīng)在"tables"配置項(xiàng)中存在,則 Presto 會(huì)從對(duì)應(yīng)的 Alluxio 集群中讀取該庫(kù)表的數(shù)據(jù)(首次從 Alluxio 中讀取時(shí),如果未有緩存,則 Alluxio 會(huì)將數(shù)據(jù)緩存下來(lái),后續(xù)的讀取會(huì)直接訪問(wèn)緩存),如果沒(méi)有在"tables"中配置,則 Presto 會(huì)直接訪問(wèn)底層的 HDFS、不經(jīng)過(guò) Alluxio。"tables"支持庫(kù)/表/分區(qū)級(jí)別的配置,支持通配符。
天穹 Presto on Alluxio 方案上線后,部分現(xiàn)網(wǎng)查詢業(yè)務(wù)得到了20%~ 30%的性能提升,數(shù)據(jù)讀取的耗時(shí)波動(dòng)幅度變小、查詢性能也更加穩(wěn)定。
4.2 Presto on K8s
Presto on K8s 是業(yè)界通用的一種部署模式,可以參考社區(qū)的presto-kubernetes-operator,天穹 Presto 根據(jù)自身的業(yè)務(wù)情況做了相應(yīng)的適配改造, 整體的部署架構(gòu)圖如下所示:
每個(gè) Presto 集群前端會(huì)部署一個(gè) CLB 騰訊云負(fù)載均衡服務(wù),對(duì)外提供統(tǒng)一的訪問(wèn)域名地址。CLB 后端掛載 Coordinator Pod,Worker 通過(guò) CLB 地址向 Coordinator 注冊(cè),客戶端也通過(guò) CLB 訪問(wèn) Presto。
天穹 Presto 集群有單獨(dú)的租戶資源,能保證集群的資源下限(Dedicated Resource),通過(guò) K8s HPA Controller 感知 Presto Worker 的 CPU 和內(nèi)存資源使用情況,實(shí)現(xiàn) Worker Pod 的動(dòng)態(tài)擴(kuò)縮容。當(dāng)白天 Presto 任務(wù)量較多需要更多資源時(shí),可以動(dòng)態(tài)擴(kuò)容 Worker 至租戶的資源上限,如果其他業(yè)務(wù)租戶有空閑的資源,也可以繼續(xù)"借用"。當(dāng)晚上 Presto 集群空閑時(shí),可以動(dòng)態(tài)縮容 Worker,將資源釋放給其他業(yè)務(wù)租戶使用,使資源池的利用率最大化。
4.3 Count Distinct Rewrite
Presto 的 Count Distinct 實(shí)現(xiàn)在某些場(chǎng)景下會(huì)造成數(shù)據(jù)傾斜的問(wèn)題,影響查詢的性能,比如在 Left Join 之后再做 Count Distinct,由于 Presto use_mark_distinct 規(guī)則的作用,會(huì)在 Left Join 之后做一次 Repartitioning,然后在下一個(gè) Stage 做 MarkDistinct,如果 Repartitioning 階段的 Partition Key 有較多重復(fù)值,那么就會(huì)造成下一個(gè) Stage 出現(xiàn)數(shù)據(jù)傾斜的問(wèn)題,影響 MarkDistinct 算子的執(zhí)行速度。如果能將 Count Distinct 改寫(xiě)成 Grouping Sets,由于 Group By 會(huì)在 Repartitioning 前做預(yù)聚合,所以能有效消除上述的數(shù)據(jù)傾斜問(wèn)題。社區(qū)也有類(lèi)似的 issue 12024,但是從該 issue 的討論內(nèi)容來(lái)看,還并未有較完善的解決方案。
目前我們通過(guò)天穹 SuperSQL 來(lái)實(shí)現(xiàn) Count Distinct 單列/多列到 Grouping Sets 的改寫(xiě),無(wú)需改動(dòng) Presto 的代碼,經(jīng)過(guò)改寫(xiě)優(yōu)化后,在某些用戶場(chǎng)景下,能獲得2 ~ 3 倍的查詢性能提升。
4.4 Optimized Repartitioning
天穹 Presto 每天的業(yè)務(wù)查詢 Exchange 的數(shù)據(jù)量達(dá)到了上百 PB 級(jí)別,為了提升 Repartitioning 階段的性能,我們?cè)谏a(chǎn)環(huán)境中啟用了社區(qū)的 Optimized Repartitioning 特性:
set session optimized_repartitioning=true; 參考 PR-13183
開(kāi)啟后,PartitionedOutputOperator 算子整體的CPU 消耗減少了 50%,P90 查詢耗時(shí)降低了 19%,某些用戶場(chǎng)景下的查詢性能提升接近 2 倍,節(jié)省了資源的同時(shí)性能也得到了較大的提升。
5 總結(jié) & 未來(lái)工作
天穹 SuperSQL的 vision 是通過(guò)構(gòu)建大數(shù)據(jù)智能融合平臺(tái),將異構(gòu)的計(jì)算引擎/異構(gòu)的存儲(chǔ)服務(wù)、計(jì)算的自動(dòng)智能優(yōu)化、流批一體的統(tǒng)一以及自治的系統(tǒng)運(yùn)維納入內(nèi)部,給使用者提供簡(jiǎn)單統(tǒng)一的邏輯入口和虛擬化的視圖方案,使得用戶能夠從繁雜的技術(shù)細(xì)節(jié)中解脫出來(lái),專(zhuān)注于業(yè)務(wù)邏輯的實(shí)現(xiàn)。未來(lái)在 Presto 的工作主要有:語(yǔ)法擴(kuò)展(臨時(shí)表/視圖的支持等)、運(yùn)維增強(qiáng)(History Server、高可用)、自適應(yīng)執(zhí)行(運(yùn)行在不同硬件規(guī)格的機(jī)器上)、內(nèi)核性能提升、數(shù)據(jù)源 Connector 擴(kuò)展增強(qiáng)等,在支撐好騰訊內(nèi)部各業(yè)務(wù)需求的同時(shí),也會(huì)積極擁抱和回饋開(kāi)源社區(qū),本篇文章的大部分內(nèi)容,我們也在 2021 年 12 月舉行的 PrestoCon 大會(huì)上做了分享PrestoCon-2021,歡迎大家持續(xù)關(guān)注。
聯(lián)系我們
如果你對(duì) SuperSQL 感興趣,歡迎聯(lián)系我們探討技術(shù)。同時(shí)我們長(zhǎng)期歡迎志同道合的大數(shù)據(jù)人才加入,歡迎咨詢。聯(lián)系方式:yikonchen@tencent.com
#有料程序員 直播#
對(duì)談中年鵝廠工程師
工作20年依然保持少年般的熱情
點(diǎn)擊預(yù)約,觀看直播
總結(jié)
以上是生活随笔為你收集整理的腾讯 PB 级大数据计算如何做到秒级?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 新一代消息队列 Pulsar
- 下一篇: 速抢免费红包封面!