問題現象
某天早上塞入大量回滾的蝦皮 Queue,卻發現一個詭異現象:
- Queue 數量完全沒有減少
- 訂單資料卻有正常進來
- Kafka Group 狀態顯示「Stable」
- Job 機綠燈正常運作
看起來一切正常,但就是不對勁。
深入調查
發現關鍵錯誤訊息
CommitFailedException: Offset commit cannot be completed since the consumer is not part of an active group for auto partition assignment; it is likely that the consumer was kicked out of the group.
問題根源分析
仔細回想回滾資料的特性:
- 已完成訂單數量龐大(約 300 張)
- 每張都要打財務資料 API
- 蝦皮有訂單數量分頁限制
- 一個 Queue 處理時間將近 1 分鐘
致命的數學
| 設定 | 數值 |
|---|---|
| 一次拉取 Queue 數 | 10 個 |
| 每個 Queue 處理時間 | 1 分鐘 |
| 總處理時間 | 10 分鐘 |
| Kafka Session Timeout | 5 分鐘(預設) |
10 分鐘 > 5 分鐘 = Consumer 被 Kafka 判定死亡!
Kafka Consumer Group 狀態表
| 狀態 | 說明 |
|---|---|
| Stable | 正常運作,已分配 Partition |
| Completing Rebalance | 正在分配 Partition |
| Preparing Rebalance | 準備重新分配,成員已停止消費 |
| Empty | Group 存在但無成員 |
| Dead | Group 已被移除 |
解決方案
- 減少一次拉取的 Queue 數量:從 10 改成 2
- 減少單一 Queue 的工作量:拆分大任務
- 調整 Timeout 設定:增加 max.poll.interval.ms
關鍵學習
Queue 設計時要評估單一 Queue 的處理時間,來決定一次拉取的最大數量。如果無法評估,就把工作拆到最小可評估單位。
相關 Kafka 參數
session.timeout.ms:心跳超時時間max.poll.interval.ms:兩次 poll 之間的最大間隔max.poll.records:一次 poll 的最大記錄數
發佈留言