kafka9重複消費問題解決
kafka9重複消費問題解決
背景:之前用的kafka客戶端版本是0.8,近期升級了kafka客戶端的版本,寫了新的消費者和生產者的程式碼,在本地測試沒有問題,可以正常消費與生產。但最近的專案中使用了新版的程式碼,當資料量較大時會出現重複消費的問題。現將問題的排除與解決過程記錄下來,避免再次踩坑。
問題發現:由於ConsumerRecord物件可以獲取到當前訊息的分割槽與偏移量,故在log日誌中將當前訊息的分割槽與偏移量也記錄下來了。在監控日誌的過程中,發現某一個分割槽的偏移量會在多個執行緒中出現,而且偏移量的值還不一樣,因此覺得可能是重複消費,當查詢程式消費的總記錄數和kafka中的訊息記錄數相差甚多。
解決過程:上網搜尋如何解決kafka重複消費的問題,都是在說kafka在session時間內未提交offset,故參考網上思路,將consumer的poll的時間改成100ms,即100ms從kafka上poll一次資料,並且設定props.put("auto.commit.interval.ms", "1000"); props.put("session.timeout.ms", "30000");kafka自動提交的時間間隔和session時間。
改完後測試,發現當kafka的資料量較大時,還是會有重複消費問題,然後將poll的資料 條數列印出來發現資料條數較多,而且一段時間後(一般30s)會報一個錯誤:
org.apache.kafka.clients.consumer.CommitFailedException:
Commit cannot be completed since the group has already rebalanced and assigned the partitions to another member.
This means that the time between subsequent calls to poll() was longer than the configured session.timeout.ms, which typically implies that the poll loop is spending too much time message processing.
You can address this either by increasing the session timeout or by reducing the maximum size of batches returned in poll() with max.poll.records. [com.bonc.framework.server.kafka.consumer.ConsumerLoop]
大概意思是:由於組已經重新平衡並將分割槽分配給另一個成員,因此無法完成提交。 這意味著在呼叫poll()的後續呼叫之間的時間比配置的session.timeout.ms長,這通常意味著poll迴圈花費太多時間訊息處理。 您可以通過增加會話超時或通過使用max.poll.records減少poll()中返回的批次的最大大小來解決此問題。
於是設定如下引數:
//一次從kafka中poll出來的資料條數
//max.poll.records條資料需要在在session.timeout.ms這個時間內處理完
props.put("max.poll.records","100");
這個數值的大小需要和session.timeout.ms的時長做評估,即100條資料在session.timeout.ms時間內是否能處理完?
注:
props.put("session.timeout.ms", "30000");
//訊息傳送的最長等待時間.需大於session.timeout.ms這個時間
props.put("request.timeout.ms", "40000");
還需要 注意的是,fetch.min.bytes這個引數配置,從kafka拉取的資料的大小,這個引數最好設定一下,不然的話可能出問題。建議設定為:
//server傳送到消費端的最小資料,若是不滿足這個數值則會等待直到滿足指定大小。預設為1表示立即接收。
props.put("fetch.min.bytes", "1");
總結:
一般情況下,kafka重複消費都是由於未正常提交offset,故修改配置,正常提交offset即可解決。上文中提到的主要配置如下所示:
/* 自動確認offset的時間間隔 */
props.put("auto.commit.interval.ms", "1000");
props.put("session.timeout.ms", "30000");
//訊息傳送的最長等待時間.需大於session.timeout.ms這個時間
props.put("request.timeout.ms", "40000");
//一次從kafka中poll出來的資料條數
//max.poll.records條資料需要在在session.timeout.ms這個時間內處理完
props.put("max.poll.records","100");
//server傳送到消費端的最小資料,若是不滿足這個數值則會等待直到滿足指定大小。預設為1表示立即接收。
props.put("fetch.min.bytes", "1");
//若是不滿足fetch.min.bytes時,等待消費端請求的最長等待時間
props.put("fetch.wait.max.ms", "1000");
相關文章
- 解決RabbitMQ訊息丟失與重複消費問題MQ
- 透過 Pulsar 原始碼徹底解決重複消費問題原始碼
- 探索RocketMQ的重複消費和亂序問題MQ
- RabbitMQ如何解決被重複消費和資料丟失的問題?MQ
- “田由甲” - Kafka重複消費線上問題暴雷Kafka
- 解決winform窗體重複建立問題ORM
- 快速解決mongodb出現id重複問題MongoDB
- Pulsar 也會重複消費?
- 解決Linq.ToDictionary()時的鍵重複問題
- 解決alertmanager重複傳送訊息的問題
- 解決生產日誌重複列印的問題
- 實際業務處理 Kafka 訊息丟失、重複消費和順序消費的問題Kafka
- kafka 消費組功能驗證以及消費者資料重複資料丟失問題說明 3Kafka
- Java IO 建立檔案解決檔名重複問題Java
- 解決spring security自定義filter重複執行問題SpringFilter
- 解決 HttpServletRequest 的輸入流不能重複讀的問題HTTPServlet
- GoLang中生產者消費者模式解決併發問題Golang模式
- 分散式環境下利用快取解決重複性問題分散式快取
- Python Requests庫文件連結404問題解決及防止重複問題的建議Python
- 如何保證訊息不被重複消費
- 阿里面試題剖析,如何保證訊息不被重複消費?阿里面試題
- RCmongodb出現id重複問題的簡單解決辦法jztMongoDB
- Spring Boot + Redis 解決陪玩平臺原始碼重複提交問題Spring BootRedis原始碼
- 測試平臺系列(82) 解決APScheduler重複執行的問題
- 靈活運用分散式鎖解決資料重複插入問題分散式
- 生產消費問題
- 解決移動端複製問題
- 《RabbitMQ》如何保證訊息不被重複消費MQ
- 【Java面試】Kafka 怎麼避免重複消費Java面試Kafka
- 8 種方案解決重複提交問題!你選擇哪一種呀?
- React Hooks學習之旅五:useMemo解決子元件重複執行問題ReactHook元件
- 用滑動視窗來解決最長無重複子串問題
- 解決csdn登陸複製的問題
- 元件複用傳值(待解決問題)元件
- Spring Cloud Stream如何處理訊息重複消費?SpringCloud
- Springboot+Redisson自定義註解一次解決重複提交問題(含原始碼)Spring BootRedis原始碼
- 簡單介紹redis分散式鎖解決表單重複提交的問題Redis分散式
- Shell 解決Redis Slow Log去重問題Redis
- Android studio glide包重複問題AndroidIDE