簡體   English   中英

如何在部署期間在 Kafka Streams 應用程序中實現高可用性?

[英]How to achieve high availability in a Kafka Streams app during deployment?

主要問題:我們在 Kubernetes 上運行 Kafka Streams (Java) 應用程序,以在我們的 Kafka 集群中消費、處理和生成實時數據(運行 Confluent Community Edition v7.0/Kafka v3.0)。 我們如何以限制使用記錄的停機時間的方式部署我們的應用程序? 我們最初的目標是每項任務單次停機時間約為2 sec

我們的目標是對生產環境的更改進行持續部署,但是部署太具有破壞性,會導致我們的應用程序中的記錄消耗停機,從而導致生成的實時記錄出現延遲。

我們嘗試了不同的策略來查看它如何影響延遲(停機時間)。

策略#1:

  • 終止所有應用程序實例(共 6 個)
  • 立即啟動所有新的應用實例
  • 結果:測量的消耗記錄的最大延遲: 85 sec

策略二:

  • 啟動一個新的應用實例
  • 等待3 minutes以允許在新應用實例中恢復本地 state
  • 3 minutes后終止一個舊應用實例
  • 重復直到所有舊的應用程序實例都被終止
  • 結果:測量的消耗記錄的最大延遲: 39 sec

策略#3:

  • 與策略 #2 相同,但將等待時間增加到15 minutes
  • 結果:測量的消耗記錄的最大延遲: 7 sec 但是,每個應用程序實例15 minutes將導致 15 分鍾 x 6 個實例 = 90 minutes來部署更改 + 額外的30 minutes以完成增量重新平衡協議。 我們發現部署時間相當長。

我們一直在閱讀KIP-429:Kafka Consumer Incremental Rebalance Protocol並嘗試配置應用程序以支持我們的用例。

以下是我們為策略 #2 和 #3 所做的關鍵 Kafka Streams 配置:

acceptable.recovery.lag: 6000
num.standby.replicas: 2
max.warmup.replicas: 6
probing.rebalance.interval.ms: 60000
num.stream.threads: 2

輸入主題有12 partitions ,消息速率平均為800 records/s 有 3 個 Kafka Streams 鍵值 State 存儲,其中兩個具有與輸入主題相同的速率。 這兩個大約是20GB size 密鑰集的大小約為4000 理論上acceptable.recovery.lag的.recovery.lag 應該是每個分區的更新日志主題延遲~60秒。

以下是策略 #3每個應用實例的一些指標(上升、接收消息的速率和接收消息的延遲): 在此處輸入圖像描述

我們所做的值得注意的觀察:

1a - 第一個新應用實例啟動

1b - Kafka 立即重新平衡,2 個舊應用程序實例被分配更多任務,2 個舊應用程序實例丟失任務

1c - 同時記錄的最大延遲從0.2 sec增加到3.5 sec (這表明重新平衡大約需要3 sec

2 - 探測重新平衡發生,Kafka Streams 以某種方式決定從一個舊應用程序實例中撤銷一項任務,並將其交給已經擁有最多任務的應用程序實例

3 - 最后一個舊的應用程序實例被終止

4 - 所有分區都像升級前一樣重新平衡,增量重新平衡完成(最后一個應用實例終止后大約33 minutes

Other - 第一個新應用實例分配任務大約需要40 minutes 此外,每個任務都被重新分配多次,導致3 sec的許多小中斷。

如果需要,我們可以為其他策略提供有關拓撲、主題、配置和指標圖的更多詳細信息(這個線程已經很大了)。

為您的 Kafka Stream 應用程序提供一些一般建議(不是專業人士,而是我個人觀察到的)。

  1. 將您的 pod 從 Deployment 更改為 StatefulSet 並添加此配置group.instance.id: "${hostname}" 通過這種方式,pod 將保持與 pod 相同的名稱,您將能夠使用Kafka Consumer Incremental Rebalance Protocol
  2. 當您現在使用 StatefulSet 時,將 state 存儲保存在永久存儲中,它將從 Kafka 中刪除 state 存儲重新加載。 但請注意,您需要根據 Kubernetes 接收到的信號正確關閉 Kafka Stream 並調整terminationGracePeriodSeconds以允許正確關閉。 如果不是,Kafka Stream 將檢測到檢查點不干凈,並將重新獲取狀態存儲(不清楚您的 state 存儲是否已持久化,但我認為它已經完成)。

我觀察到的唯一一件事是簡單的消費者組再平衡比您預期的 2 秒要長,這似乎是一個復雜的目標(就像您說的重新平衡需要 3 秒)。 但是使用增量重新平衡,我認為在重新平衡期間將處理一些分區(暫時沒有親自測量)。

我無法發表評論(由於對 SO 比較陌生),所以我會在這里回復。 您關於 StatefulSet 和滾動重啟的觀點是正確的,但您可以通過在 StatefulSet 中使用podManagementPolicy: Parallel來解決這個問題。 這使得它與部署相同,因為所有 pod 都將同時出現。

https://kubernetes.io/docs/concepts/workloads/controllers/statefulset/#pod-management-policies

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM