擴展基於Kafka的工作負載最佳實踐

Apache Kafka 以其能夠實時處理大量事件的能力而聞名。然而,為了處理數百萬個事件,我們在實施 Kafka 生產者服務和消費者服務時需要遵循某些最佳實踐。

在開始之前使用 Kafka 在您的項目中,讓我們了解何時應該使用 Kafka:

  • 高容量事件流。當您的應用程序/服務生成連續的事件流,如用戶活動事件,網站點擊事件,傳感器數據事件,日誌事件或股市更新時,Kafka 處理大量事件並具有低延遲的能力非常有用。
  • 實時分析。Kafka 對於構建實時數據處理管道特別有幫助,其中需要在數據到達時立即進行處理。它允許您將數據流式傳輸到分析引擎,如 Kafka streams、Apache Spark 或 Flink 進行即時分析/洞察和流式或批處理。
  • 解耦應用程序。作為一個中央消息中心,它可以解耦應用程序的不同部分,從而實現獨立開發和服務的擴展,並鼓勵負責任的分離原則。
  • 系統間的數據整合在整合分散系統時,Kafka 能夠高效地在不同應用之間轉移數據,作為可靠的數據代理。

與其他佇列系統的主要區別

以下是 Apache Kafka 與 ActiveMQ、ZeroMQ 和 VerneMQ 等系統的區別:

持久存儲

Kafka 將事件存儲在分散的日誌中,允許隨時重播數據,即使在系統/節點故障的情況下也能實現數據持久性,不同於某些傳統消息佇列,這些佇列可能依賴於像 Redis 這樣的內存存儲。

分區

數據在代理/主題之間進行分區,實現大數據流的並行處理和高吞吐量。這有助於消費者線程連接到單個分區,促進橫向擴展性。

消費者組

多個消費者可以訂閱相同的主題,並從分區內的不同偏移量讀取,允許不同團隊以重複消費模式來消費和處理相同數據以滿足不同目的。一些例子包括:

  • ML 團隊消費的用戶活動以檢測可疑活動
  • 推薦團隊建立推薦系統
  • 廣告團隊生成相關廣告

Kafka 生產者最佳實踐

批次大小和延遲時間

透過配置 batch.sizelinger.ms,您可以提高您的 Kafka 生產者 的吞吐量。batch.size 是批次的最大大小(以位元組計)。Kafka 將嘗試在發送給生產者之前將其批次化。

linger.ms 決定生產者將等待的最大時間(以毫秒計),以便等待額外消息添加到批次進行處理。

配置 batch sizelinger.ms 設定,通過控制在發送到處理系統之前累積多少數據,顯著幫助系統性能,使其在處理大量數據時實現更好的吞吐量和降低延遲。根據所選的值,也可能會引入輕微的延遲。特別是,較大的批次大小與正確的 linger.ms 組合可以優化數據傳輸效率。

壓縮

另一種增加吞吐量的方法是通過compression.type配置啟用壓縮。生產者可以在將數據發送到代理之前使用gzipsnappylz4對數據進行壓縮。對於大量數據,此配置有助於通過網絡效率減少壓縮開銷。它還可以節省帶寬並增加系統的吞吐量。此外,通過設置適當的序列化器和鍵序列化器,我們可以確保數據序列化為與您的消費者兼容的格式。

重試和幂等性

為確保Kafka生產者的可靠性,應該啟用重試和幂等性。通過配置retries,生產者可以在指定的嘗試次數內自動重新發送任何未獲代理確認ack的數據批次。

確認

此配置控制在考慮消息成功發送之前從代理獲得的確認級別。通過選擇適當的acks級別,您可以控制應用程序的可靠性。以下是此配置的接受值。

  • 0 – 最快,但無法保證消息傳遞。
  • 1 – 一旦寫入主代理,消息即被確認,提供基本可靠性。
  • all – 只有當所有副本都確認後,消息才被視為已傳遞,確保高耐用性。

基於工作負載的配置調整

你應該開始追蹤指標,如消息發送速率、批量大小和錯誤率,以識別性能瓶頸。定期檢查並根據功能/數據修改或更新調整生產者設置。

Kafka 消費者最佳實踐

消費者群組

每個 Kafka 消費者 應該屬於一個消費者群組;一個消費者群組可以包含一個或多個消費者。通過在群組中創建更多的消費者,您可以擴展以從所有分區讀取,從而處理大量的數據。group.id 配置可幫助識別消費者屬於的消費者群組,從同一主題消費的多個消費者之間實現負載均衡。最佳實踐 是使用有意義的群組 ID 輕鬆識別應用程序內的消費者群組。 

偏移提交

您可以控制應用程序何時提交偏移量,這有助於避免數據丟失。提交偏移量有兩種方式:自動和手動。對於高吞吐量應用程序,您應該考慮手動提交以提高控制。

  • auto.offset.reset – 定義當消費者開始消費一個沒有提交偏移的主題時應該做什麼(例如,一個新主題或消費者第一次加入組時)。 選項包括earliest(從開頭讀取)、latest(從結尾讀取)或none(拋出錯誤)。 在大多數情況下選擇”earliest”,以避免新消費者加入組時遺漏數據。控制消費者如何開始消費數據,確保當消費者重新啟動或加入組時行為正確。
  • enable.auto.commit幫助配置 自動定期提交偏移。通常,我們對於大多數生產場景將值設置為false,我們不需要高可靠性,在應用邏輯內手動提交偏移以確保精確一次處理。提供控制以管理偏移提交,從而更好地控制數據處理。
  • auto.commit.interval.ms 如果 enable.auto.commit 設置為 true,則自動提交偏移量的毫秒間隔。根據應用程序的處理時間進行修改,以避免因意外故障而導致的數據丟失。 

提取大小和最大輪詢記錄

此配置幫助控制每個請求中檢索的記錄數,配置 fetch.min.bytesmax.poll.records。增加此值可以幫助提高應用程序的吞吐量,同時減少 CPU 使用率並減少對代理的調用次數。

  • fetch.min.bytes – 在單個輪詢請求中從代理提取的最小字節數。 設置一個小值以避免不必要的網絡調用,但不要設置得太小以免造成過度輪詢。它有助於通過防止小而頻繁的請求來優化網絡效率。 
  • fetch.max.bytes 最大 每次請求從一個broker中拉取的字節數。 根據可用內存調整,以防止過度加載消費者工作進程。這樣可以減少 一次請求中檢索的數據量,從而避免內存問題。
  • max.poll.interval.ms – 在超時之前等待請求返回數據的最大時間。 設置一個合適的超時時間,以避免消費者出現卡頓/延遲,如果數據不可用。這有助於防止 消費者長時間等待消息而被卡住。 (有時候,如果活性探測受影響,k8s pods可能會重新啟動)。

分區分配

這是分配分區(partition.assignment.strategy)給群組內消費者的策略(例如,rangeroundrobin)。 對於大多數情況,使用range來均勻分配分區給消費者。這有助於 在群組中實現消費者之間的平衡負載分配。

在使用Kafka之前,請考慮以下一些重要事項:

  • 複雜性實施 Kafka 需要對分散式系統概念有更深入的理解,例如分區和偏移管理,因為它具有先進的功能和配置。
  • 監控和管理。實施監控和 Kafka 叢集管理對於確保高可用性和性能非常重要。
  • 安全性實施穩健的安全實踐以保護流經 Kafka 主題的敏感數據也很重要。

實施這些最佳實踐可以幫助您擴展基於 Kafka 的應用程序,以處理數百萬/十億的事件。然而,重要的是要記住,最佳配置可能會根據您的應用程序的具體要求而有所不同。

Source:
https://dzone.com/articles/best-practices-for-scaling-kafka-based-workloads