背景
業務場景中需要抓取異構系統中的數據,自然想到了鼎鼎有名開源的ETL工具Kettle,網上說8的版本還有諸多問題,這里采用較老的7.1.0.0.-12
測試場景
1、運行環境
我使用了Kettle的Carte組件,將Kettle進行了Docker容器化打包,在服務器上部署運行,由於是測試,服務器的硬件配置不是特別高
類別 | cpu | 內存 | 磁盤 |
---|---|---|---|
配置 | 2核心 | 4G | 500G |
2、運行的jvm參數
-XX:+AggressiveOpts
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=/tmp
-XX:InitialHeapSize=1073741824
-XX:MaxHeapSize=2147483648
-XX:MaxMetaspaceSize=268435456
-XX:+PrintCommandLineFlags
-XX:+PrintGCDateStamps
-XX:+PrintGCDetails
-XX:+UseG1GC
3、運行的JRE版本
openjdk version "1.8.0_111"
OpenJDK Runtime Environment (build 1.8.0_111-8u111-b14-2~bpo8+1-b14)
OpenJDK 64-Bit Server VM (build 25.111-b14, mixed mode)
4、源庫的情況
源庫為Postgres,目標庫也為Postgre,源庫中約為590萬數據。
5、kettle工程
通過表輸入從源表中讀取數據,通過插入/更新將數據寫入目標庫表。
6、運行
通過Kettle spoon連接數據庫資源庫,提交轉換至服務端的Carte運行。
測試結果
1、過多次反復測試發現到處理到500萬條記錄數時候就開始OutOfMemoryError: Java heap space
2、GCView分析gc.log日志分析如下圖
3、Memory Analyzer分析dump文件,提示有內存泄漏
本人對kettle的源碼不是特別了解,所以無法繼續深入分析,粗略判斷org.pentaho.di.core.logging.MetricsRegistry未釋放,導致內存持續增長從而OOM。
One instance of "org.pentaho.di.core.logging.MetricsRegistry" loaded by "java.net.URLClassLoader @ 0x800287c8" occupies 2,062,205,928 (96.24%) bytes.
至此,感覺離勝利遙遙在望,但是總是不清楚是哪里有問題導致內存泄漏,不清楚是我使用的問題,還是本身Kettle該版本程序的問題,望各位大佬指點!如果有需要可以提供dump文件供分析。
如果有需要可以提供dump文件供分析,請入群聯系索取!
結論
注意,此段為找到原因后補充的內容。
通過反復測試及長時間折騰,最終發現原因后竟哭笑不得,期間嘗試過各種方法
- 向pentaho_kettle提交bug,未果
- 懷疑是該版本的問題,對比了github上kettle的7.1大版本后續的版本的代碼,嘗試尋找是否有對這問題的處理,未果
- 嘗試編譯7.1系列中最新的版本7.1.0.0-32,驗證新版本是否還有此問題,未果
最終在一次偶然的反復驗證操作步驟過程中注意到了一個選項的關鍵字中包含了Metrics,於是立馬取消勾選改選項,然后仿佛真的就是這個問題,一切都好了。
如圖,該選項在默認的是勾選的(略坑),在執行的時候一定要取消勾選,否則導致內存泄漏。