現象
使用者反饋 hs2 開啟的檔案描述符的數量一直在漲,但是當前 hs2 的連線只有個位數。
排查過程
首先找到 hs2 程序持有了哪些檔案描述符,透過 lsof 命令 lsof -p $pid
,看到 hs2 程序確實在 /data/emr/hive/tmp/operation_logs/
目錄下開啟了大量描述符
在 jira 中找到一個類似 的 issue: [HIVE-10970] Investigate HIVE-10453: HS2 leaking open file descriptors when using UDFs - ASF JIRA (apache.org)
但是這個場景是由於 UDF 導致的 fd 洩漏,並且洩漏路徑是在 hive.downloaded.resources.dir
路徑下,跟 operation_logs 目錄不一樣.看上去不是同一個問題
排查原始碼 , 找到 operation log 有一個清理邏輯org.apache.hive.service.cli.operation.Operation#cleanupOperationLog
猜測是在客戶端 session 異常結束 的時候,這個方法沒有被正常呼叫到或者清理邏輯有漏洞導致的
首先過一遍 session 關閉的邏輯,透過分析 beeline 客戶端的火焰圖,找到 session 關閉起始點org.apache.hive.jdbc.HiveStatement#closeClientOperation
這裡 client 發起了一個 thrift rpc 呼叫,然後在 hs2 thrift 找到 thrift server 對應的方法 org.apache.hive.service.cli.thrift.ThriftCLIService#CloseOperation
跟蹤這個方法,最終會走到 org.apache.hive.service.cli.operation.SQLOperation#close
這裡會呼叫 cleanupOperationLog 方法
那麼確實是有可能由於客戶端 session 異常退出,operation logs 沒有被清理的可能的
接著檢視 cleanupOperationLog 邏輯, 看這裡是否有程式碼 bug ,於是在 idea 中使用 git 分支比較功能,發現 3.1 版本提交了一個修復
[HIVE-18820] Operation doesn't always clean up log4j for operation log - ASF JIRA (apache.org)
結論
- 客戶端 session 異常退出,導致 operation logs 沒有被清理,跟 scratch dir 沒有被清理場景類似
- HIVE-18820 社群 bug 導致,可以考慮合入這個 patch