kafka shutdown停止關閉很慢問題的解決方案

Zollty發表於2016-12-31


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後將執行緒強行殺死,作為臨時解決方案。



相關文章