Presto因其優秀的查詢速度被我們所熟知,它本身基於MPP架構,可以快速的對Hive數據進行查詢,同時支持擴展Connector,目前對Mysql、MongoDB、Cassandra、Hive等等一系列的數據庫都提供了Connector進行支持。是我們常用的SQL on Hadoop的解決方案。那么我們今天就來看一下,當我們選擇Presto作為我們的查詢引擎之后,我們需要考慮的問題。
Presto 性能調優和穩定性
Presto 存在的問題
- Coordinator單點問題(常見方案:ip漂移、nginx代理動態獲取等)
- 大查詢容易OOM(0.186+版本支持dump到磁盤 未驗證)
- 沒有容錯能力,無重試機制
- Presto部署環境復雜,MPP架構容易受到單台機器影響
- Presto並發能力不足
調優策略
- 部署多台Coordinator避免單點問題,上層封裝一層查詢服務 避免jdbc直連
- 如果有必要在查詢服務進行重試操作(需要判斷任務狀態)
- 對worker相關內存參數進行合理配置,避免OOM
- 啟用Presto本身資源隊列的同時,構建符合業務場景的查詢隊列,控制並發量及查詢優先級,確保任務高效完成
- 開發Presto監控系統,監測Presto集群狀態,及時預警。動態調整Presto集群規模
內存調優
Presto分為三類內存池,分別為GENERAL_POOL、RESERVED_POOL、SYSTEM_POOL。
SYSTEM_POOL是系統預留內存,worker初始化和執行任務必要的內存,默認為Xmx0.4 也可由resources.reserved-system-memory指定 RESERVED_POOL是最大查詢內存,Presto會將當前好用內存最大的query切到該內存區域,默認為Xmx0.1 由query.max-memory-per-node配置
GENERAL_POOL其他查詢內存,即除最大查詢外其他query的查詢內存,大小為Xmx-SYSTEM_POOL-RESERVED_POOL
整體內存配置受以下場景的影響:
- 用戶查詢數據量、復雜性(決定該用多大的查詢內存)
- 用戶查詢的並發度(決定該用多大的jvm堆)
需要注意的是:單純的增大RESERVED_POOL的值並不能解決Presto的查詢問題,因為RESERVED_POOL大部分時間是不參與計算的,只有滿足以下情景才會被使用,而且只能被一個Query所使用。
- GENERAL_POOL有節點出現阻塞節點的情況,即內存不足
- RESERVED_POOL沒有被使用
所以三者需要配置合理的值,如果並發比較大需要SYSTEM_POOL保持默認或者稍微再大一點,RESERVED_POOL可以稍微增大到八分之一左右。
同時對於jvm OOM的問題,需要對Presto的jvm.config進行配置:
-XX:G1ReservePercent=15
-XX:InitiatingHeapOccupancyPercent=40
-XX:ConcGCThreads=8
Presto監控
Presto自帶的監控頁面只能顯示當前Presto集群的狀態和最近的部分查詢,不能滿足需求。需要對查詢相關信息進行數據采集:
- 查詢基本信息(狀態、內存使用、總時間、錯誤信息等)
- 查詢性能信息(每一步的時間、數據輸入輸出數據量信息等,包括stage詳情和stage下task的詳情)
- 異常預警
Presto后續優化
- 控制分區表最大查詢分區數量限制
- 控制單個查詢生成的split數量上限,防止計算資源大量消耗
- 自動發現並殺死長時間運行的查詢
- Presto查詢限流(限制超過xx數據量的查詢)
- 啟用Presto資源隊列
- 統一查詢引擎
Presto當前版本內存限制和管理
單機維度
- GENERAL_POOL每次內存申請時,都會判斷內存使用量是否超過了最大內存,如果超過了就報錯,錯誤為“Query exceeded local memory limit of x”,這保護了Presto會無限申請內存,只會導致當前查詢出錯。同時,如果該節點的GENERAL_POOL可使用內存以及可回收內存為0,那么認為該node為Block node。
- RESERVED_POOL可以認為是查詢最大的SQL,其能滿足GENERAL_POOL的內存限制策略,那么肯定會滿足RESERVED_POOL的策略(復用了GENERAL_POOL策略)。
- RESERVED_POOL目前版本未發現可以限制內存,所以當並發非常高,且scan的數據非常大時,有低概率會引起OOM問題。但是配合Resource Group,內存設置合理,也基本會避免OOM問題。
集群維度
同時滿足以下兩點時,Presto便認為集群超出要求的內存了:
- GENERAL_POOL出現阻塞節點(Block node)
- RESERVED_POOL已經被使用
- 當判斷出集群超出CLuster Memory時,有兩種方式管理內存:
- 挨個遍歷每個查詢,判斷當前查詢占用的總內存是否超過了query.max-memory(config.properties里配置),如果超過了,那么該查詢就被failed。
- 如果query.max-memory配置的不合理,值非常大,那么可能過了5秒(默認時間)依然不滿足第一種情形,那么將會使用第二種方法管理查詢。第二種管理方法又分為兩種小的管理,根據LowMemoryKillerPolicy來決定Kill查詢策略,其分為total-reservation和total-reservation-on-blocked-nodes。配置total-reservation的作用是kill掉所有查詢里最費內存的查詢;而total-reservation-on-blocked-nodes殺死在內存不足(阻塞)的節點上使用最多內存的查詢。
Resource Groups
Resource Groups 可以認為是Presto實現了一個弱資源限制和隔離功能。其可以為每個group指定隊列大小、並發大小、內存使用大小。為每個group設置合理的hardConcurrencyLimit(最大並發數)、softMemoryLimit(內存最大使用值)及maxQueued(隊列大小)一方面可以使不同業務影響降低,另一方面也大概率避免OOM問題,當然善於運用user及做下二次開發,就可以讓Presto支持多用戶共用同一分組和權限認證功能。
參考資料:
http://armsword.com/2018/05/22/the-memory-management-and-tuning-experience-of-presto/
歡迎關注我:叄金大數據