探索Kafka消費者的內部結構

banq發表於2022-07-25

Adobe使用Kafka處理資料的流量規模:310B msg/day300 TB/day IN920 TB/day OUT,今天我們將分享我們在 Kafka Client 內部的專業知識。
Kafka Consumer 是一個從 Kafka 消費訊息的客戶端。

探索Kafka消費者的內部結構
組成:

  • 消費者後設資料——管理消費者所需的後設資料:叢集中的主題和分割槽、充當分割槽領導者的代理節點等。
  • Subscriptions — 跟蹤消費者訂閱狀態
  • 反序列化器——記錄鍵和值反序列化器。反序列化器將位元組陣列轉換為物件。
  • Partition Assignor — 完全限定的類名,表示實現org.apache.kafka.clients.consumer.ConsumerPartitionAssignor的分割槽分配策略
  • 攔截器——可能改變記錄的攔截器
  • Consumer Coordinator — 管理組成員、偏移量
  • 網路客戶端——處理對代理的請求
  • Fetcher——從經紀人那裡獲取成批的記錄。


配置 Kafka 消費者
Kafka Consumer 有四個必需的屬性:

  • bootstrap.servers — 用於建立與 Kafka 叢集的初始連線的主機/埠對列表。格式:“host1:port1,host2:port2,...”
  • key.deserializer — 完全限定的類名,表示實現org.apache.kafka.common.serialization.Deserializer介面的金鑰反序列化器。
  • value.deserializer — 完全限定的類名,表示實現org.apache.kafka.common.serialization.Deserializer介面的值反序列化器。
  • group.id — 唯一的消費者組 ID。如果客戶端使用 subscribe() 方法來消費訊息或使用偏移量管理功能,則需要。


訂閱主題
Kafka Consumer 提供了兩種訂閱主題的方式:透過subscribe()assign()方法每個都有一組不同的受支援功能。

subscribe()

  • 支援訂閱主題列表或使用正規表示式
  • 具有消費者故障檢測的組成員身份(客戶端和伺服器端)
  • 動態分割槽分配
  • 自動或手動偏移管理
  • 每個分割槽單個消費者(使用標準分割槽分配器)

assign()

  • 使用主題分割槽訂閱進行更精細的控制
  • 自動或手動偏移管理
  • 每個分割槽支援多個消費者

Apache Flink 和 Spark 使用assign()來訂閱主題並管理主題-分割槽對在工作人員之間的分佈。

消費訊息
訂閱主題後,使用者可以透過呼叫poll()方法來使用訊息。根據訂閱方法,在幕後會發生幾個呼叫,在下面的序列圖中列出。
使用 subscribe() 消費

探索Kafka消費者的內部結構
subscribe()的情況下,Kafka Consumer 在成為消費者組的活躍成員之前不會消費記錄。我們看到一些團隊錯過了這一點,花時間除錯停止消費,而根本原因是不穩定的消費群體

使用 assign()

探索Kafka消費者的內部結構
assign()的情況下,Kafka Consumer 不會呼叫組成員功能,例如心跳和加入/重新加入消費者組。

提取器Fetcher
無論訂閱方式如何,Kafka Consumer 都使用 Fetcher 從 broker 中檢索批記錄。

探索Kafka消費者的內部結構
Fetcher 將 Producer 傳送的壓縮批次儲存在記憶體中,並在poll() 上解壓縮記錄。一旦批次被消耗,它就會從記憶體中丟棄。fetch.min.bytesfetch.max.wait.ms是用於調整 fetcher 吞吐量或延遲的關鍵配置。增加位元組和時間將導致吞吐量增加並減少更好的延遲。

消費群
當使用者使用subscribe()進行消費時,具有相同group.id的消費者將組成一個消費者組,共同消費 topic(s) 訊息。Kafka 叢集將選舉其中一個代理作為Group Coordinator。組協調器負責管理組列表成員、接收心跳、觸發組成員更改的重新平衡等。協調器將選舉一個消費者作為組領導,並要求在消費者之間進行分割槽分配。每個分割槽將只分配一個消費者。

探索Kafka消費者的內部結構

消費者群體再平衡
組成員身份的更改將觸發消費者組重新平衡。在重新平衡期間,組長將重新計算當前成員之間的分割槽分配。重新平衡觸發時

  • 消費者加入群組
  • 消費者離開群體
  • 透過max.poll.interval.ms檢測到客戶端故障
  • 透過session.timeout.ms檢測到伺服器端故障

可能觸發消費者組重新平衡的可能原因列表:
  • 在我們的 OUT 中擴充套件服務
  • poll() 和長訊息處理發生在同一個執行緒中
  • 組協調員心跳失敗
  • JVM 垃圾收集暫停
  • Kubernetes PODS CPU 受到限制
  • Kubernetes 叢集升級,導致 POD 被驅逐
  • 網路問題(延遲、丟包等)


消費者分割槽分配器
Kafka Consumer 提供了幾個選項來選擇在重新平衡期間如何分配分割槽。使用者可以透過partition.assignment.strategy配置引數來控制它,使用實現org.apache.kafka.clients.consumer.ConsumerPartitionAssignor的完全限定類名的值。開箱即用的 Kafka 提供了以下策略:

  • Range - 停止世界策略,以主題為基礎。它可能會產生不平衡的分配。更多細節javadoc
  • RoundRobin——停止世界策略,為相同的訂閱統一分配分割槽。更多細節在javadoc中。
  • Sticky — 停止世界策略,初始分發將接近RoundRobin。嘗試最小化重新平衡期間移動的分割槽,可能會產生不平衡的分配。更多細節在javadoc中。
  • CooperativeSticky —在不停止消費的情況下進行增量再平衡。這與 Sticky 的邏輯相同,但具有增量支援。這種策略可能會產生不平衡的分配。更多細節在javadoc中。

相關文章