一、當前配置
Flink:版本1.4
Flink-Kafka-Connector:0.10.x
Kafka-Brokers:3個
Topic-Partitoins:3個
Topic-Replication:2個
二、現象描述
Flink通過Kafka-Connector連接Kafka消費數據,當Kafka異常,Broker節點不可用時,Kafka的Consumer線程會把Flink進程的CPU打爆至100%其中:
- 一個節點不可用時:Flink可以恢復
- 二個節點不可用時:CPU持續100%
- 三個節點不可用時:CPU持續100%
三、問題分析:
CPU持續高,首先想到是Flink在消費數據時沒有對異常進行處理,頻繁異常打爆了CPU,我們去檢查Flink的輸出日志,輸出日志並沒有找到有價值的信息,初次分析宣告失敗。
沒辦法,只能用動用大殺器,分析下進程的CPU占用了線程以及堆棧
1、查看占用CPU高的進程,確認無誤這些進程全是Flink的JOP

2、打印進程堆棧
jstack 10348>> 10348.txt 得到進程的所有線程堆棧信息。
3、查找占用CPU高的線程
ps -mp pid -o THREAD,tid,time 查找占用cpu搞的線程
4、查看線程堆棧,發現大部分錯誤集中在KafkaConsumer.poll方法上。

到這基本可以定位原因了,應該是Kafka的ConsumerPoll方法導致CPU高。
圍繞KafkaConsumer需要指定排查計划,主要是兩個方向
1、Kafka和Flink跟Poll相關的參數調整。
2、Kafka和Flink對Kafka消費時是否有Bug。
中間確實嘗試了好多條路,其中
1、驗證調整了KafkaConsumer的max.poll.interval.ms參數,不起作用。
2、Kafka的相關Jop並沒有進行重啟,所以不需要調整Flink重試相關的參數。
3、調整Flink的flink.poll-timeout參數,不起作用。
最終發現,原來是Kafka-Consumer0.10版本的一個Bug。
詳細的Bug描述如下:https://issues.apache.org/jira/browse/KAFKA-5766。
有了Bug解決起來就迅速多了,根據Bug制定解決驗證方案:
1、升級Flink的Kafka-ConnnectorAPI。
2、調整reconnect.backoff.ms參數。
此時升級Flink的Kafka-Connector就解決了該問題。
中間還出現一個小插曲:因為我們的復制因子是2,當其中兩個節點宕機后,CPU也暴增到100%。增加了不少彎路。后分析,只有兩個復制因子,1個Parition分布在兩個Broker上,假如兩個Broker宕機,其實是和三個集群宕機影響是一樣的。
三、事后總結
1、Kafka-Topic的復制因子和分區要根據實際需要需求設置。假如有三個節點,重要的業務Topic建議分區3個,復制因子3個,用性能換穩定。
2、Kafka的0.10版的Consumer消費時,有Bug,Broder節點異常關閉時,Client會打爆CPU,0.11及以上修復。
3、Flink版本的Kafka-Connector,0.11可以消費0.10的Kafka.
