kafka shutdown停止很慢問題
在資料量大的時候,consumer一次抓取資料的資料很多,進入到業務處理的資料可能有很多,
假設一次poll有1萬條資料進入業務程式,而且業務程式是和poll繫結在一起執行緒同步執行的,假設平均每條資料,執行業務程式花費100ms,
那麼poll一次的資料,至少要執行 1w*0.1s = 1000s = 16.67分鐘。
所以,在資料量大的時候,停止一個執行緒(需要先等待業務程式處理完資料),可能要十幾分鍾。
shutdown問題解決方案
1、改成非同步處理資料,consumer取出來的資料,放到BlockQueue中,由非同步執行緒去處理,當非同步執行緒處理不過來時,阻塞consumer,呼叫consumer.pause()方法avoid group management rebalance,程式碼如下(來源於Spring-Kafka):
// avoid group management rebalance due to a slow consumer this.consumer.pause(this.assignedPartitions.toArray(new TopicPartition[this.assignedPartitions.size()])); public void onPartitionsAssigned(Collection<TopicPartition> partitions) { this.assignedPartitions = partitions; }
2、如果是同步執行資料處理,考慮提高業務程式 處理資料的速度。
3、同步處理資料,但是改成手動提交offset,當shutdown的時候,poll的資料不需要全部處理,只需要記錄處理的位置即可。程式碼示例如下:
list data = consumer.poll(); for(record: data) { if(shutdown) { // 收到shutdown命令後立即停止,未處理的資料將丟棄 break; } deal(record); saveTopicOffset(record); } submitDealtDataOffset();
另外,
Kafka停不掉shutdown關閉不了問題
原因是卡在了consumer.close()方法裡面,它會提交offset資訊,如果網路中斷或者kafka伺服器有問題導致提交不了offset,則consumer.close方法會一直卡住(不停的迴圈嘗試提交offset,永不中斷)。
參見:Kafka poll一直等待的bug:
https://issues.apache.org/jira/browse/KAFKA-4189?jql=project%20%3D%20KAFKA%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20consumer%20ORDER%20BY%20priority%20DESC
https://issues.apache.org/jira/browse/KAFKA-3172?jql=project%20%3D%20KAFKA%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20consumer%20ORDER%20BY%20priority%20DESC
解決方法:目前還沒有好的辦法,只能將offset的自動提交改成手動提交offset。但是,我寫了一個程式可以在呼叫consumer.close後將執行緒強行殺死,作為臨時解決方案。