Flink-cdc2.1 分片算法導致GC問題


一、背景
目前 yarn 集群 360 個FLink實時作業,90% 都是使用 flink1.13.3 + cdc2.1 ,在12月17號發現一個流任務:xxx_mysql_kafka 運行無異常,但是一直不往 Kafka 發送最新數據

二、問題排查
1、 根據該任務 application id 查看具體運行在那個 yarn 節點上

  1. 堡壘機登錄該節點,切換到 yarn 用戶下,使用 jstat -gcutl pid 查看該 jvm 進程,發現頻繁 young gc 且 full gc 次數過多,達到 30 次

查看到 FUll GC 非常頻繁

  1. 使用 jmap 將該 jvm 進程的 heap 內存 dump 下來,用 mat 進行分析:/usr/java/jdk1.8.0_144/bin/jmap -dump:format=b,file=3512.hprof 3512,將 dump 文件導入 mat 中

  1. 根據 mat 提示信息,定位問題代碼,發現出現問題的對象是 ResultSetImpl ,這是從 MySQL 讀取數據用到的對象。

使用 idea 打開 flink-cdc-connector 的代碼,分支切換到 release-2.1 ,查看 MySqlSnapshotSplitReadTask 類的代碼,問題出現下面這一段代碼,flink-cdc 從 MySQL 讀取數據,然后發送到下游,異常的是這一批次讀取出來的對象有 50w+ 條,這應該是出問題的具體原因

5、排查這一批次分片讀取 50W 數據的原因,任務啟動時設置的 chunk.size 為 2w,理論上應該每批次讀取 2w 才對,查看 flink-cdc 源碼,具體的分片操作在 ChunkSplitter類的 splitTableIntoChunks 函數

因為抽取的表主鍵類型是 bigint ,所以觸發了 flink-cdc 的分片優化邏輯,雖然我們配置的 chunk.size 是 2w,但是經過 flink-cdc 內部優化,優化后的 chunk.size 為 2w * 120 = 240w 左右

具體的分片優化邏輯如下:

a. 計算該表數據的分布因子:最大主鍵id - 最小主鍵 id = 主鍵最大最小差

b. 主鍵最大最小差 / 該表數據量 = 數據分布因子

c. 數據分布因子 * 任務啟動輸入的 chunk.size = 優化后的分片大小

出問題表的計算過程:(202112061064180438(最大主鍵) - 202112061000977284(最小主鍵) / 529696(該表數據量) = 119.3197(數據分布因子),最終的分片大小為 119.3197*2w = 240w,

因為該表數據的最大id與最小id差值較大,但是該表數據量只有 50w+,導致 flink-cdc 做了一個反向優化,最后出問題了

查看該任務的 jobmnager 日志,驗證了上面的猜測,該表的最終分片大小為:2443667

  1. 出現問題的具體原因已經找到,解決方案

     a. 降低 split-key.even-distribution.factor.upper-bound 比例,默認為 1000,可調至 10,這樣最大批次的數據量為 10*chunk.size
    
     b. 不使用增量抽數模式:snapshot :scan.incremental.snapshot.enabled = false
    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM