理解Kafka offset

大資料技術前線發表於2023-09-25

來源:waynblog

日常開發中,相信大家都對 Kafka 有所耳聞,Kafka 作為一個分散式的流處理平臺,一般用來儲存和傳輸大量的訊息資料。在 Kafka 中有三個重要概念,分別是 topic、partition 和 offset。

  • topic 是 kafka 中的訊息以主題為單位進行歸類的邏輯概念,生產者負責將訊息傳送到特定的主題,消費者負責訂閱主題並進行消費。
  • partition 是 topic 的物理概念,每個 topic 可以細分為多個 partition,每個 partition 只屬於單個 topic,並且包含不同的訊息,partition 用於提高 topic 的儲存和消費的效能和可擴充套件性,可以將 topic 分散在多個 broker 上,並支援多個 consumer 並行消費。
  • offset 是 partition 中每條訊息的唯一標識,是一個單調遞增且不變的值,由 kafka 自動維護,offset 用於定位和記錄訊息在 partition 中的位置和消費進度,保證 partition 內的訊息有序。

本文將給大家介紹 offset 的相關概念,大綱如下

  • offset 的作用和意義
  • offset 的儲存和管理
  • offset 的提交和重置
  • offset 的消費和保證

offset 的作用和意義

理解Kafka offset

offset 是 Kafka 為每條訊息分配的一個唯一的編號,它表示訊息在分割槽中的順序位置。offset 是從 0 開始的,每當有新的訊息寫入分割槽時,offset 就會加 1。offset 是不可變的,即使訊息被刪除或過期,offset 也不會改變或重用。

offset 的作用主要有兩個:

  • 一是用來定位訊息。透過指定 offset,消費者可以準確地找到分割槽中的某條訊息,或者從某個位置開始消費訊息。
  • 二是用來記錄消費進度。消費者在消費完一條訊息後,需要提交 offset 來告訴 Kafka broker 自己消費到哪裡了。這樣,如果消費者發生故障或重啟,它可以根據儲存的 offset 來恢復消費狀態。

offset 的儲存和管理

offset 的儲存和管理主要涉及到兩個方面:生產者端和消費者端。

生產者端

生產者在向 Kafka 傳送訊息時,可以指定一個分割槽鍵(Partition Key),Kafka 會根據這個鍵和分割槽演算法來決定訊息應該傳送到哪個分割槽。如果沒有指定分割槽鍵,Kafka 會採用輪詢或隨機的方式來選擇分割槽。生產者也可以自定義分割槽演算法。

當訊息被寫入到分割槽後,Kafka broker 會為訊息分配一個 offset,並返回給生產者。生產者可以根據返回的 offset 來確認訊息是否成功寫入,並進行重試或其他處理。

消費者端

消費者在消費 Kafka 訊息時,需要維護一個當前消費的 offset 值,以及一個已提交的 offset 值。當前消費的 offset 值表示消費者正在消費的訊息的位置,已提交的 offset 值表示消費者已經確認消費過的訊息的位置。

消費者在消費完一條訊息後,需要提交 offset 來更新已提交的 offset 值。提交 offset 的方式有兩種:自動提交和手動提交。

  • 自動提交:Kafka 提供了一個配置引數 enable.auto.commit,預設為 true,表示開啟自動提交功能。自動提交功能會在後臺定期(由 auto.commit.interval.ms 引數控制)將當前消費的 offset 值提交給 Kafka broker。
  • 手動提交:如果 enable.auto.commit 設定為 false,則表示關閉自動提交功能,此時消費者需要手動呼叫 commitSync 或 commitAsync 方法來提交 offset。手動提交功能可以讓消費者更靈活地控制何時以及如何提交 offset。

無論是自動提交還是手動提交,offset 的實際儲存位置都是在 Kafka 的一個內建主題中:__consumer_offsets。這個主題有 50 個分割槽(可配置),每個分割槽儲存一部分消費組(Consumer Group)的 offset 資訊。Kafka broker 會根據消費組 ID 和主題名來計算出一個雜湊值,並將其對映到 __consumer_offsets 主題的某個分割槽上。

__consumer_offsets 主題是 Kafka 0.9.0 版本引入的新特性,之前的版本是將 offset 儲存在 Zookeeper 中。但是 Zookeeper 不適合大量寫入,因此後來改為儲存在 Kafka 自身中,提高了效能和可靠性。

offset 的提交和重置

提交 offset 是消費者在消費完一條訊息後,將當前消費的 offset 值更新到 Kafka broker 中的操作。提交 offset 的目的是為了記錄消費進度,以便在消費者發生故障或重啟時,能夠從上次消費的位置繼續消費。

重置 offset 是消費者在啟動或執行過程中,將當前消費的 offset 值修改為其他值的操作。重置 offset 的目的是為了調整消費位置,以便在需要重新消費或跳過某些訊息時,能夠實現這個需求。

提交 offset

提交 offset 的方式有兩種:自動提交和手動提交。前面已經介紹過這兩種方式的區別和用法,這裡不再贅述。需要注意的是,無論是自動提交還是手動提交,都不保證提交成功。因為 Kafka broker 可能發生故障或網路延遲,導致提交失敗或延遲。因此,消費者需要處理提交失敗或延遲的情況。

  • 提交失敗:如果提交失敗,消費者可以選擇重試或放棄。重試的話,可能會導致多次提交同一個 offset 值,但是不會影響正確性,因為 Kafka broker 會忽略重複的 offset 值。放棄的話,可能會導致下次啟動時重新消費已經消費過的訊息,但是不會影響完整性,因為 Kafka 訊息是冪等的。
  • 提交延遲:如果提交延遲,消費者可以選擇等待或繼續。等待的話,可能會導致消費速度變慢,或者超過 session.timeout.ms 引數設定的時間而被認為已經死亡。繼續的話,可能會導致下次啟動時漏掉一些沒有提交成功的訊息。

重置 offset

重置 offset 的方式有兩種:手動重置和自動重置。手動重置是指消費者主動呼叫 seek 或 seekToBeginning 或 seekToEnd 方法來修改當前消費的 offset 值。自動重置是指消費者在啟動時根據 auto.offset.reset 引數來決定從哪個位置開始消費。

  • 手動重置:手動重置可以讓消費者精確地控制從哪個位置開始消費。例如,如果想要重新消費某個分割槽的所有訊息,可以呼叫 seekToBeginning 方法將 offset 設定為 0;如果想要跳過某個分割槽的所有訊息,可以呼叫 seekToEnd 方法將 offset 設定為最大值;如果想要從某個具體的位置開始消費,可以呼叫 seek 方法將 offset 設定為任意值。
  • 自動重置:自動重置可以讓消費者在啟動時根據 auto.offset.reset 引數來決定從哪個位置開始消費。auto.offset.reset 引數有三個可選值:earliest, latest 和 none。earliest 表示從最早的可用訊息開始消費;latest 表示從最新的可用訊息開始消費;none 表示如果沒有可用的 offset,則丟擲異常。

offset 的消費和保證

offset 的消費和保證主要涉及到兩個方面:順序性和一致性。

順序性

順序性是指 Kafka 訊息是否按照傳送和接收的順序進行處理。Kafka 只保證分割槽內的順序性,即同一個分割槽內的訊息按照 offset 的順序進行傳送和接收。但是不保證主題內或跨主題的順序性,即不同分割槽內的訊息可能會亂序傳送和接收。因此,如果需要保證主題內或跨主題的順序性,需要在生產者和消費者端進行額外的處理,例如使用同一個分割槽鍵或同一個消費組。

一致性

一致性是指 Kafka 訊息是否能夠被正確地傳送和接收,不會出現丟失或重複的情況。Kafka 提供了三種不同級別的一致性保證:最多一次(At most once),最少一次(At least once)和精確一次(Exactly once)。

  • 最多一次:最多一次是指 Kafka 訊息只會被髮送或接收一次或零次,不會出現重複的情況,但是可能會出現丟失的情況。這種保證的實現方式是在生產者端關閉重試功能,在消費者端在消費訊息之前提交 offset。這種保證適用於對訊息丟失不敏感的場景,例如日誌收集或監控。
  • 最少一次:最少一次是指 Kafka 訊息只會被髮送或接收一次或多次,不會出現丟失的情況,但是可能會出現重複的情況。這種保證的實現方式是在生產者端開啟重試功能,在消費者端在消費訊息之後提交 offset。這種保證適用於對訊息重複不敏感的場景,例如計數或累加。
  • 精確一次:精確一次是指 Kafka 訊息只會被髮送或接收一次,不會出現丟失或重複的情況。這種保證的實現方式是在生產者端和消費者端使用事務功能,在消費者端使用冪等功能。這種保證適用於對訊息丟失和重複都敏感的場景,例如轉賬或支付。

最後,希望本文能夠對您理解 kafka offset 有所幫助,感謝閱讀。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70027827/viewspace-2985683/,如需轉載,請註明出處,否則將追究法律責任。

相關文章