PPT的內(nèi)容是去年在部門內(nèi)部做的關(guān)于Presto入門分享,主要涉及的內(nèi)容如下圖所示:
由于簡(jiǎn)書不支持嵌入iframe,所以具體的內(nèi)容放在騰訊文檔上面了:
Presto中有很多的基本概念畅买,只有理解好這些基本概念,我們才能更好的理解Presto,下面是我梳理的各種概念的腦圖:
接下來(lái)的部分是關(guān)于當(dāng)時(shí)分享后的一些Q&A:
1.Presto的task是如何在Worker節(jié)點(diǎn)間分配的姜挺,按什么策略進(jìn)行分配的?
Presto中task
可以分為兩種彼硫,一種是leaf stages
的task炊豪,另一種是intermediate stages
的task。
(1)leaf stages的task一般都是表掃描拧篮,讀取數(shù)據(jù)词渤,過(guò)濾、解壓串绩、解碼等操作缺虐,這些操作可以進(jìn)行高度的并行化。所以在這一階段源數(shù)據(jù)會(huì)被劃分成盡可能多的splits
礁凡,因此每一個(gè)Worker上都可能會(huì)啟動(dòng)一個(gè)task來(lái)處理分配到此Worker上的splits(而每個(gè)split的大小高氮,Worker上可被處理的split個(gè)數(shù)都是由相應(yīng)的參數(shù)來(lái)控制的)。
(2)對(duì)于intermediate stages的中的每一個(gè)stage
的task數(shù)把篓,又是基于多種配置來(lái)確定的纫溃,如connector
的配置,執(zhí)行計(jì)劃的屬性韧掩,中間數(shù)據(jù)的位置以及集群部署配置等信息來(lái)確定的紊浩。
(3)集群常用的配置信息如下所示:
- 內(nèi)存管理相關(guān)的參數(shù):
user memory
一般是輸入文件以及執(zhí)行程序時(shí)所使用的內(nèi)存,system memory
一般是伴隨著程序執(zhí)行而使用到的內(nèi)存,如shuffle buffers等疗锐。
參數(shù) | 示意 |
---|---|
query.max-memory-per-node | 每個(gè)Worker上一個(gè)query可用的最大user memory坊谁,默認(rèn)JVM max memory * 0.1 |
query.max-total-memory-per-node | 每個(gè)Worker上一個(gè)query可用的最大user memory+system memory,默認(rèn)JVM max memory * 0.3 |
query.max-memory | 整個(gè)集群中一個(gè)query可用的最大user memory滑臊,默認(rèn)20GB |
query.max-total-memory | 整個(gè)集群中一個(gè)query可用的最大user memory+system memory口芍,默認(rèn)query.max-memory * 2 |
- 節(jié)點(diǎn)管理相關(guān)的參數(shù):
參數(shù) | 示意 |
---|---|
node-scheduler.max-splits-per-node | 每個(gè)Worker可被執(zhí)行的最大splits數(shù),默認(rèn)100 |
node-scheduler.max-pending-splits-per-task | 每個(gè)Worker上雇卷,每個(gè)query的stage的task的等待隊(duì)列中可容納的最大splits數(shù)鬓椭,默認(rèn)10 |
- hive-connector相關(guān)參數(shù):
參數(shù) | 示意 |
---|---|
hive.max-split-size | hive-split的最大size颠猴,默認(rèn)64M |
總的來(lái)說(shuō),一個(gè)stage可以被劃分成多個(gè)task小染,每一個(gè)task只會(huì)運(yùn)行在一個(gè)Worker上(比如我們線上Presto集群有20個(gè)節(jié)點(diǎn)翘瓮,那么一個(gè)query當(dāng)中的一個(gè)stage最多可以有20個(gè)task在并行執(zhí)行)。而每個(gè)stage具體分配多少個(gè)task是和相應(yīng)的配置信息息息相關(guān)的裤翩。
2.Presto處理壓縮文件時(shí)內(nèi)存如何分配资盅,如何處理壓縮文件,內(nèi)存大小如何做預(yù)估踊赠?
Presto是通過(guò)插件的方式來(lái)支持不同類型的文件格式呵扛,如ORC、Parquet以及RCFile等筐带。對(duì)于不同格式的文件會(huì)有對(duì)應(yīng)reader
今穿,比如對(duì)于Parquet文件就對(duì)應(yīng)著ParquetReader,ParquetReader主要的作用是通過(guò)hive-connector獲得源數(shù)據(jù)的信息(包括目標(biāo)文件在hdfs的block列表烫堤,以及地址等信息)荣赶,并將數(shù)據(jù)轉(zhuǎn)換成Presto中對(duì)應(yīng)的數(shù)據(jù)對(duì)象(如split
凤价,page
鸽斟,block
等)。接著會(huì)根據(jù)列不同的數(shù)據(jù)類型(int利诺、boolean富蓄、timestamp等)來(lái)讀取相應(yīng)column下的數(shù)據(jù)。在讀取數(shù)據(jù)的時(shí)候慢逾,如果數(shù)據(jù)是壓縮數(shù)據(jù)立倍,首先會(huì)對(duì)數(shù)據(jù)進(jìn)行解壓后再做處理。讀取壓縮數(shù)據(jù)并解壓的代碼如下所示:
對(duì)于parquet文件侣滩,其PageHeader類中有記錄當(dāng)前page的壓縮和未壓縮文件大小口注,所以在解壓的時(shí)候,程序知道需要向
MemoryPool
申請(qǐng)多少內(nèi)存君珠。Presto的內(nèi)存管理涉及的內(nèi)容比較多寝志,我這里就簡(jiǎn)單做一下介紹,Presto在啟動(dòng)的時(shí)候會(huì)新建一個(gè)MemoryPool
策添,所有的任務(wù)都是通過(guò)該MemoryPool去申請(qǐng)內(nèi)存材部,而Presto在執(zhí)行任務(wù)的每一個(gè)階段都會(huì)有相應(yīng)的MemoryContext
記錄該階段所使用的的內(nèi)存詳情。而Presto可以通過(guò)各種參數(shù)(如上面提到過(guò)的幾個(gè)內(nèi)存管理相關(guān)的參數(shù))來(lái)限制一個(gè)query
在集群中可用的最大內(nèi)存以及一個(gè)query在每一個(gè)Worker上可用的內(nèi)存唯竹,只要當(dāng)前MemoryPool還有可用的內(nèi)存并且申請(qǐng)的內(nèi)存在參數(shù)限制的范圍內(nèi)乐导,相應(yīng)的query就能夠獲得執(zhí)行內(nèi)存。如果query未申請(qǐng)到相應(yīng)的內(nèi)存會(huì)有相應(yīng)的query kill策略進(jìn)行處理浸颓。
3.task掛了物臂,是不是所有的stage都要重新執(zhí)行旺拉,以及Presto是如何做容錯(cuò)的?
目前棵磷,Presto可以通過(guò)低級(jí)別的重試從臨時(shí)的錯(cuò)誤中恢復(fù)(比如账阻,出現(xiàn)請(qǐng)求錯(cuò)誤時(shí),會(huì)發(fā)送多次請(qǐng)求來(lái)獲得結(jié)果)泽本。至于整個(gè)任務(wù)的失敗淘太,需要依靠client端的重新發(fā)起查詢請(qǐng)求。目前规丽,在facebook的生產(chǎn)環(huán)境中是通過(guò)額外的機(jī)制保證某種特定場(chǎng)景下的高可用(如standby coordinators蒲牧、run multiple active cluster以及通過(guò)監(jiān)控系統(tǒng)來(lái)確定失敗的節(jié)點(diǎn)并將節(jié)點(diǎn)移出集群再重新加入集群等)。Presto后續(xù)會(huì)添加對(duì)于長(zhǎng)時(shí)間查詢?nèi)蝿?wù)的容錯(cuò)支持赌莺,如添加checkpointing以及執(zhí)行計(jì)劃子樹的重試(不過(guò)冰抢,就目前更新的版本來(lái)看還未添加該特性)。
4.sql的執(zhí)行計(jì)劃以及結(jié)果等是否緩存艘狭?相同的表不同where條件是否有做緩存挎扰?
該部分未找到可以參考的資料,但是從如下三方面來(lái)看巢音,數(shù)據(jù)應(yīng)該是未做緩存的:
(1)從源碼來(lái)看在Coordinator中不管是生成語(yǔ)法樹遵倦、邏輯執(zhí)行計(jì)劃以及物理執(zhí)行計(jì)劃時(shí),都未看到有做緩存處理官撼;
(2)而在Worker上梧躺,每一個(gè)task都有與之對(duì)應(yīng)的taskid,stage間的不同的task 在進(jìn)行shuffle的時(shí)候都是通過(guò)唯一的taskid來(lái)進(jìn)行數(shù)據(jù)傳輸?shù)陌列澹看稳蝿?wù)請(qǐng)求的taskid各不相同掠哥。并且shuffle請(qǐng)求的client端在接收到了shuffle的server端發(fā)送的結(jié)果數(shù)據(jù)后,會(huì)向server端發(fā)送token確認(rèn)信息秃诵,server端確認(rèn)client端接收到數(shù)據(jù)之后會(huì)刪除結(jié)果數(shù)據(jù)续搀,因此Worker端也未緩存查詢的結(jié)果以及中間結(jié)果數(shù)據(jù)。
(3)在Presto集群比較空閑的情況下菠净,一條sql在Presto中執(zhí)行多次禁舷,查詢時(shí)間以及資源利用情況基本差不多,未見明顯差異嗤练。
參考資料:
[1] Presto: SQL on Everything https://prestosql.io/Presto_SQL_on_Everything.pdf
[2] Presto配置信息 https://prestodb.io/docs/current/admin/properties.html
[3] Presto 0.214版源碼