Presto記憶體管理相關引數設定

2021-10-10 10:01:46 字數 3601 閱讀 8312

之前介紹過presto記憶體管理和分配策略,但是那個是0.192版本,詳細見:presto記憶體管理原理和調優 ,0.201之後記憶體管理作了新的修改,所以重新簡單分析下,然後給出乙個配置模板,希望對使用presto的同學有幫助。

presto裡面記憶體只有2種記憶體,一種是user memory,另一種是system memory。system memory用於input/output/exchange buffers等,user memory 用於hash join、agg這些。

0.201之前有3種記憶體pool,分別是general_pool、reserved_pool及system_pool。但是0.201之後,預設system_pool是不開啟的,以下引數控制,預設值為false

deprecated.legacy-system-pool-enabled那system_pool不使用了,這塊記憶體怎麼控制呢,去**裡確認了下:

sqltaskmanager#createquerycontext

private querycontext createquerycontext(queryid queryid,localmemorymanager localmemorymanager,nodememoryconfig nodememoryconfig,

localspillmanager localspillmanager,

gcmonitor gcmonitor,

datasize maxqueryusermemorypernode,

datasize maxquerytotalmemorypernode,

datasize maxqueryspillpernode)

return new defaultquerycontext(

queryid,

maxqueryusermemorypernode,

maxquerytotalmemorypernode,

localmemorymanager.getgeneralpool(),

gcmonitor,

tasknotificationexecutor,

driveryieldexecutor,

maxqueryspillpernode,

localspillmanager.getspillspacetracker());

}

}

可以看到systempool.get()被替換為了localmemorymanager.getgeneralpool(),所以general_pool扮演了之前general_pool及system_pool的作用,提供user memory和system memory。

說完system_pool,再說下reserved_pool,reserved_pool作用就是當general_pool滿的時候,將最占用記憶體的sql分配到這塊記憶體上來,但是實際使用時,這塊記憶體很少會被使用,原因是, 一般使用presto的業務是用來sql提速的,不會使用spill disk功能,第二為了服務的穩定性,會限制最大記憶體和kill記憶體策略,所以會出現查詢沒有被分配到reserved_pool之前, sql將會被系統kill掉。第三是大查詢一般會用spark/hive替代,所以這塊reserved_pool就會浪費掉了,如下圖所示:

目前有9個sql正在查詢,都在使用general_pool,reserved_pool將會浪費掉。所以對於絕大部分presto使用者,禁止掉reserved_pool是正確的選擇。

memory.heap-headroom-per-node這個記憶體主要是第三方庫的記憶體分配,無法被統計跟蹤,預設值是xmx*0.3。

所以,presto記憶體分配只需要考慮general_pool及heap-headroom-per-node。

既然presto是乙個純記憶體olap引擎,那肯定不能讓查詢占用的記憶體無限大,需要引數控制sql占用的最大記憶體,presto記憶體管理包括了單機和集群粒度的記憶體,分別是:

而集群query.max-memory由query.initial-hash-partitions控制,預設值為8,那query.max-memroy 一般稍小於query.max-memory-per-node*8即可(考慮到資料傾斜)。

根據**和上面分析知道:

reserved_pool = query.max-total-memory-per-node

所以新的 general_pool = totalmemory - reservedpool - memory.heap-headroom-per-node

禁止掉reserved_pool時:

general_pool= totalmemory - memory.heap-headroom-per-node

綜上,presto合適的記憶體分配配置為如下,假如-xmx80g,worker數大於8臺:

query.max-memory=120gb # 預設為20gb,query.max-memory-per-node * 8 * 0.8 ,傾斜按照0.8算即可query.max-memory-per-node=20gb # 預設值0.1 * xmx,一般線上按照0.25*xmx算,這個最好結合自己併發,如果併發大,大查詢多,值最好小一點,穩定性考慮query.max-total-memory-per-node=32gb # 預設值0.3*xmx,一般設定為0.4*xmxexperimental.reserved-pool-enabled=false # 不使用reserved_pool

memory.heap-headroom-per-node=16gb # 預設0.3*xmx,一般使用的是0.2*xmx

query.low-memory-killer.policy=total-reservation-on-blocked-nodes # kill策略,乾掉blocked的最大查詢,general_pool滿了,防止oom

比如上面分配後,general_pool為80gb - 16gb = 64gb,如下圖所示,reserved_pool不再存在。query.max-total-memory預設值為2*query.max-memory,這個引數可以保持預設值即可。

記憶體管理相關函式

記憶體分配及釋放相關函式 void calloc int num,int size 在記憶體中動態地分配 num 個長度為 size 的連續空間,並將每乙個位元組 共num size 個 都初始化為 0。void malloc int num 在堆區分配一塊指定大小的記憶體空間,用來存放資料。這塊記...

記憶體管理相關 記憶體布局 記憶體管理方案

ios系統下的記憶體布局 最上面是核心區,最下面是保留區,中間是給程式載入的空間。從高位址到低位址依次為核心區 棧 堆 靜態全域性區 未初始化區域.bss和已初始化區域.data 區 保留區 程式被載入到記憶體分成三段未初始化資料 bss 已初始化資料 data 和 段 text 段顧名思義存放 已...

QT 相關類記憶體管理

qt記憶體自動釋放兩個前提條件 1 必須是qobject的派生類 2 必須指定了qt類parent物件,則,qt 中 父類被刪除的時候會自動銷毀子類。注意 qt的析構順序先入先出,因此在指定父類時,需要如果建立在棧上 例項化產生,棧的特性 先入後出,先出 需要父類在前例項化,或是堆上 new實現 如...