背景
最近線上的 trino 叢集 master 節點老是因為 OOM crash,我們注意到 trino crash 前叢集正在執行的查詢數量正常,不太像是因為併發查詢資料太多導致的 OOM。遂配置 trino master 的 jvm,使其在崩潰後生成一份 dump 檔案,方便我們進行問題排查。
排查問題過程
收集到了 Trino master oom dump 檔案,用 mat 工具對其分析得出報告。
從報告得知,trino master crash 前有一條查詢消耗掉了大量資源,還有一大堆的 DeleteFileIndex 例項也消耗掉很多資源。
我們有收集 trino 上所有的查詢語句,透過 query_id 定位到那條異常 SQL。初看 SQL 邏輯,沒太大問題,應該不會導致 trino master oom。
於是找一個 trino 叢集做故障還原,發現併發執行 異常SQL 4條,master 就會 crash。
於是進 trino-master 容器內,用 arthas 實時觀察 jvm 狀況。
發現當 異常SQL 發起查詢時,jvm 內 iceberg-work-pool 執行緒的 cpu 暫用率會飆升到 100%,且此時 jvm 記憶體也在飆升,過程持續 20s,剛好是異常SQL 生成執行計劃所花費的時間。
然後使用 arthas 檢視 iceberg-work-pool 執行緒在幹嘛?發現其在呼叫 DeleteFileIndex 這個類,在報告裡面也是屬於 top 10 comsumer 。
看棧資訊,得到資訊在掃描 iceberg 的 manifestlist 時,會去掃描已刪除的檔案。猜測大機率是需要找到已刪除的資料 和 現在存在的資料 做一個 merge,才是當前快照的真實資料。
於是分析 懷疑表 nft_orders_v2 的後設資料資訊,發現 snapshow 裡需要讀取大量的刪除檔案。
snapshots
而 Trino 是使用 merge on read 模式進行 merge/update/delete 操作的,這樣的話每次查詢時,得掃描 "delete file" 來和 "data file" 進行合併,得出真實資料。
所以問題就出現在這,由於該表每半小時生產一次,底層存在大量的 'delete file' ,每次查詢時都要掃描這些 'delete file' 然後做 merge 操作生成執行計劃。這步操作消耗掉很多 cpu資源和記憶體資源,導致 trino master 節點崩潰。
解決方案
使用 trino 的小檔案合併功能,重寫底層資料檔案即可修復。
ALTER TABLE nft_orders_v2 EXECUTE optimize (file_size_threshold => '100MB')
為了規避此類問題再次分析,還需要找出哪些查詢的查詢計劃時間大於 10s,找出這些查詢並分析用到的表的後設資料是否合理,不合理要及時修正。