最佳實踐|從Producer 到 Consumer,如何有效監控 Kafka

語言: CN / TW / HK

對於運維人而言,如何安裝維護一套監控系統,或如何進行技術選型,從來不是工作重點。如何藉助工具對所需的應用、元件進行監控,發現並解決問題才是重中之重。

隨著 Prometheus 逐漸成為雲原生時代可觀測標準,為了幫助更多運維人用好 Prometheus,阿里云云原生團隊將定期更新 Prometheus 最佳實踐系列。第一期我們講解了《最佳實踐|Spring Boot 應用如何接入 Prometheus 監控》,今天將為大家帶來,訊息佇列產品 Kafka 的監控最佳實踐。

本篇內容主要包括三部分:Kafka 概覽介紹、常見關鍵指標解讀、如何建立相應監控體系。

什麼是 Kafka

Kafka 起源

Kafka 是由 Linkedin 公司開發,並捐贈給 Apache 軟體基金會的分散式釋出訂閱訊息系統,Kafka 的目的是通過 Hadoop 的並行載入機制來統一線上和離線的訊息處理,也是為了通過叢集來提供實時的訊息。

1.png

Kafka 的誕生是為了解決 Linkedin 的資料管道問題,用作 LinkedIn 的活動流(Activity Stream)和運營資料處理管道(Pipeline)的基礎。起初 Linkedin 採用 ActiveMQ 進行資料交換,但當時的 ActiveMQ 無法滿足 Linkedin 對資料傳遞系統的要求,經常出現訊息阻塞或者服務無法正常訪問等問題。Linkedin 決定研發自己的訊息佇列,Linkedin 時任首席架構師 Jay Kreps 便開始組建團隊進行訊息佇列的研發。

Kafka 特性

相較於其他訊息佇列產品,Kafka 存在以下特性:

  • 永續性:訊息被持久化到本地磁碟,並且支援資料備份防止資料丟失;
  • 高吞吐:Kafka 每秒可以處理百萬條訊息;
  • 可擴充套件:Kafka 叢集支援熱擴充套件;
  • 容錯性:允許叢集中節點失敗(若副本數量為 n,則允許 n-1 個節點失敗);
  • 高併發:支援數千個客戶端同時讀寫。

與此同時,區別於其他訊息佇列產品,Kafka 不使用 AMQP 或任何其他預先存在的協議進行通訊,使用基於 TCP 的自定義二進位制協議。並具有強大的排序語義和永續性保證。

Kafka 應用場景

基於以上的特性,Kafka 通過實時的處理大量資料以滿足各種需求場景:

  • 大資料領域:如網站行為分析、日誌聚合、應用監控、流式資料處理、線上和離線資料分析等領域。
  • 資料整合:將訊息匯入 ODPS、OSS、RDS、Hadoop、HBase 等離線資料倉庫。
  • 流計算整合:與 StreamComput e、E-MapReduce、Spark、Storm 等流計算引擎整合。

Kafka 技術架構

一個訊息佇列 Kafka 版叢集包括 Producer、Kafka Broker、Consumer Group、Zookeeper。

2.png

  • Producer:訊息釋出者,也稱為訊息生產者, 通過 Push 模式向 Broker 傳送訊息。傳送的訊息可以是網站的頁面訪問、伺服器日誌,也可以是 CPU 和記憶體相關的系統資源資訊。

  • Broker:用於儲存訊息的伺服器。Broker 支援水平擴充套件。Broker 節點的數量越多,叢集吞吐率越高。

  • Consumer Group:Consumer 被稱為訊息訂閱者或訊息消費者,負責向伺服器讀取訊息並進行消費。Consumer Group 指一類 Consumer,這類 Consumer 通常接收並消費同一類訊息,且訊息消費邏輯一致。通過 Pull 模式從 Broker 訂閱並消費訊息。

  • Zookeeper:管理叢集配置、選舉 Leader 分割槽,並在 Consumer Group 發生變化時進行負載均衡。其中值得一提的是,如果沒有 ZooKeeper 就無法完成 Kafka 部署。ZooKeeper 是將所有東西粘合在一起的粘合劑

  • 釋出/訂閱模型 :Kafka 採用釋出/訂閱模型,Consumer Group 和 Topic 的對應關係是 N : N,即一個 Consumer Group 可以同時訂閱多個 Topic,一個 Topic 也可以被多個 Consumer Group 同時訂閱。雖然一個Topic可以被多個 Consumer Group 同時訂閱,但該 Topic 只能被同一個 Consumer Group 內的任意一個 Consumer 消費。

監控 Kafka 的關鍵指標

這裡我們根據 Kafka 雲服務以及自建 Kafka 兩個不同的產品進行講解。

如果使用的 Kafka 是雲廠商提供的託管服務,對外暴露的指標相對有限,可以忽略 Zookeeper 相關指標。以阿里雲 Kafka 舉例,主要針對各資源型別進行監控:

1、例項監控項

  • 例項訊息生產流量(bytes/s)

  • 例項訊息消費流量(bytes/s)

  • 例項磁碟使用率(%)-例項各節點中磁碟使用率的最大值

2、Topic 監控項

  • Topic 訊息生產流量(bytes/s)

  • Topic 訊息消費流量(bytes/s)

3、Group 監控項

  • Group 未消費訊息總數(個)

如果使用自建 Kafka,那麼需要關注的指標就非常多,主要包含以下四個方向:Broker、Producer、Consumer、Zookeeper。

3.jpeg

Broker 指標

由於所有訊息都必須通過 Broker 才能被使用,因此,對 Broker 進行監控並預警非常重要。Broker 指標關注:Kafka-emitted 指標、Host-level 指標、JVM 垃圾收集指標。

  • Broker - Kafka-emitted 指標

  • 未複製的分割槽數:UnderReplicatedPartitions(可用性)kafka.server:type=ReplicaManager,name=UnderReplicatedPartitions

在執行正常叢集中,同步副本(ISR)數量應等於副本總數。如果分割槽副本遠遠落後於 Leader,則從 ISR 池中刪除這個 follower。如果代理不可用,則 UnderReplicatedPartitions 指標急劇增加。Tips:UnderReplicatedPartitions 較長時間內大於零,需要進行排查。

  1. 同步副本(ISR)池縮小/擴充套件的速率:IsrShrinksPerSec / IsrExpandsPerSec(可用性)kafka.server:type=ReplicaManager,name=IsrShrinksPerSec

Tips:如果某副本在一段時間內未聯絡 Leader 或者 follower 的 offset 遠遠落後於 Leader,則將其從 ISR 池中刪除。因此,需要關注 IsrShrinksPerSec / IsrExpandsPerSec 的相關波動。IsrShrinksPerSec 增加,不應該造成 IsrExpandsPerSec 增加。在擴充套件 Brokers 叢集或刪除分割槽等特殊情況以外,特定分割槽同步副本(ISR)數量應保持相對穩定。

  1. 離線分割槽數(僅控制器):OfflinePartitionsCount(可用性)kafka.controller:type=KafkaController,name=OfflinePartitionsCount

顧名思義,主要統計沒有活躍 Leader 的分割槽數。Tips:由於所有讀寫操作僅在分割槽載入程式上執行,因此該指標出現非零值,就需要進行關注,防止服務中斷。

  1. 叢集中活動控制器的數量:ActiveControllerCount(可用性)kafka.server:type=ReplicaManager,name=IsrShrinksPerSec

Tips:所有 brokers 中 ActiveControllerCount 總和始終等於 1,如出現波動應及時告警。Kafka 叢集中啟動的第一個節點將自動成為Controller且只有一個。Kafka 叢集中的Controller負責維護分割槽 Leader 列表,並協調 Leader 變更(比如某分割槽 leader 不可用)。

  1. 每秒 UncleanLeader 選舉次數:UncleanLeaderElectionsPerSec(可用性)kafka.controller:type=ControllerStats,name=UncleanLeaderElectionsPerSec

在可用性和一致性之間,Kafka 默選了可用性。當 Kafka Brokers 的分割槽 Leader 不可用時,就會發生 unclean 的 leader 選舉。當作為分割槽 Leader 的代理離線時,將從該分割槽的 ISR 集中選舉出新的 Leader。Tips:UncleanLeaderElectionsPerSec 代表著資料丟失,因此需要進行告警。

  1. 特定請求(生產/提取)用時:TotalTimeMs(效能)kafka.network:type=RequestMetrics,name=TotalTimeMs,request={Produce|FetchConsumer|FetchFollower}

TotalTimeMs 作為一個指標族,用來衡量服務請求(包括生產請求,獲取消費者請求或獲取跟隨者請求)的用時,其中涵蓋在請求佇列中等待所花費的時間 Queue,處理所花費的時間 Local,等待消費者響應所花費的時間 Remote(僅當時requests.required.acks=-1)傳送回覆的時間 Response。

Tips:正常情況下 TotalTimeMs 應該近似靜態且只有非常小的波動。如果發現異常,需要檢查各個佇列、本地、遠端和響應值,定位導致速度下降的確切請求段。

  1. 傳入/傳出位元組率:BytesInPerSec / BytesOutPerSec(效能)kafka.server:type=ReplicaManager,name=IsrShrinksPerSec

Tips:我們可以考慮是否啟用訊息的端到端壓縮等優化措施。磁碟吞吐量、網路吞吐量都可能成為 Kafka 的效能瓶頸。比如跨資料中心傳送訊息且 Topic 數量眾多,或副本恰好是 Leader。

  1. 每秒請求數:RequestsPerSec(效能)kafka.network:type=RequestMetrics,name=RequestsPerSec,request={Produce|FetchConsumer|FetchFollower},version=([0-9]+)

通過 RequestsPerSec,瞭解 Producer、Consumer、Followers 的請求率,確保 Kafka 的高效通訊。

Tips:請求率會隨著 Producer傳送更多流量或叢集擴充套件而增加,從而增加需要提取訊息的 Consumer 或 Followers。如果 RequestsPerSec 持續高企,需要考慮增加 Producer、Consumer、Followers。通過減少請求數量來提高吞吐量,減少非必要開銷。

  • Broker - Host 基礎指標 & JVM 垃圾收集指標

除了主機級別的相關指標,由於 Kafka 是由 Scala 編寫且執行在 JVM 上,需要依賴 Java 的垃圾回收機制來釋放記憶體,並隨著叢集活躍度提升,垃圾回收頻率不斷提升。

  1. 消耗磁碟空間消耗與可用磁碟空間:Disk usage(可用性)由於 Kafka 將所有資料持久儲存到磁碟,因此需要監視 Kafka 可用磁碟空間量。

  2. 頁面快取讀取與磁碟讀取的比率:Page cache reads ratio(效能)類似於資料庫 cache-hit ratio 快取命中率,該指標越高讀取速度越快,效能越好。如果副本追上了 Leader(如產生新代理),則該指標短暫下降。

  3. CPU 使用率:CPU usage(效能)CPU 很少是效能問題根因。但如果發生 CPU 使用率暴漲,最好還是檢查一下。

  4. 網路位元組傳送/接收(效能)代理託管其他網路服務情況下。網路使用率過高可能是效能下降的先兆。

  5. JVM 執行垃圾回收程序總數:CollectionCount(效能)java.lang:type=GarbageCollector,name=G1 (Young|Old) Generation

YoungGarbageCollector 相對經常發生。在執行時所有應用執行緒都會暫停,因此該指標的波動會造成 Kafka 效能的波動。

  1. JVM 執行垃圾收集程序用時:CollectionTime(效能)java.lang:type=GarbageCollector,name=G1 (Young|Old) Generation

OldGarbageCollector 釋放老堆疊中未使用的記憶體,雖然也會暫停應用執行緒,但只是間歇執行。如果該動作的耗時或者發生頻次過高,需要考慮是否有相應的記憶體支撐。

Producer 指標

Producer 將訊息推送到 Broker 進行消費。如果 Producer 失敗,Consumer 將沒有新訊息。因此,我們需要監測以下指標,保障穩定的傳入資料流。

  1. 每秒收到的平均響應數: Response rate(效能)kafka.[producer|consumer|connect]:type=[consumer|producer|connect]-node-metrics,client-id=([-.\w]+),node-id=([0-9]+)

對於 Producer,響應率表示從 Brokers 收到的響應率。收到資料後,Brokers 對 Producer 做出響應。結合 request.required.acks 實際配置,“收到”具備不同含義,比如:Leader 已將訊息寫入磁碟,Leader 已從所有副本收到確認已將資料寫入磁碟。在收到確認之前,Producer 資料不可用於消費。

  1. 每秒傳送的平均請求數: Request rate(效能)kafka.network:type=RequestMetrics,name=RequestsPerSec,request={Produce|FetchConsumer|FetchFollower},version=([0-9]+)

請求速率指 Producer 將資料傳送給 Brokers 的速率。速率走勢是保障服務可用性的重要指標。

  1. 平均請求等待時長: Request latency average(效能)kafka.[producer|consumer|connect]:type=[consumer|producer|connect]-node-metrics,client-id=([-.\w]+),node-id=([0-9]+)

從呼叫 KafkaProducer.send()到 Producer 收到來自 Broker 的響應之間的時長。Producer 的 linger.ms 值確定在傳送訊息批之前將等待的最長時間,這允許它累積大量訊息,再在單個請求中傳送它們。如果增加 linger.ms 提高 Kafka 吞吐量,則應關注請求延遲,確保不會超過限制。

  1. 每秒平均傳出/傳入位元組數:Outgoing byte rate(效能)kafka.producer:type=producer-metrics,client-id=([-.w]+)

瞭解 Producer 效率,並定位可能的傳輸延遲原因。

  1. I / O 執行緒等待的平均時長: I/O wait time(效能)kafka.[producer|consumer|connect]:type=[producer|consumer|connect]-metrics,client-id=([-.\w]+)

  2. 每個分割槽每個請求傳送的平均位元組數:Batch size(效能)

kafka.producer:type=producer-metrics,client-id=([-.w]+)

為了提升網路資源使用率,Producer 嘗試在傳送訊息前將訊息分組。Producer 將等待累積由 batch.size 定義的資料量,等待時長受 linger.ms 約束。

Consumer 指標

  1. Consumer 在此分割槽上滯後於 Producer 的訊息數:Records lag/Records lag max(效能)kafka.consumer:type=consumer-fetch-manager-metrics,partition="{partition}",topic="{topic}",client-id="{client-id}"

該指標用來記錄 Consumer 當前的日誌偏移量和 Producer 的當前日誌偏移量之間的計算差。如果 Consumer 是處理實時資料,則始終較高的滯後值可能表示使用者過載,在這種情況下,配置更多使用者和將 Topic 劃分到更多分割槽中提高吞吐量並減少滯後。

  1. 特定 Topic 每秒平均消耗的位元組數: bytes consumed rate(效能)kafka.consumer:type=consumer-fetch-manager-metrics,client-id="{client-id}",topic="{topic}"

  2. 特定 Topic 每秒平均消耗的記錄數: records consumed rate(效能)kafka.consumer:type=consumer-fetch-manager-metrics,client-id="{client-id}",topic="{topic}"

  3. Consumer 每秒獲取的請求數: fetch rate(效能)kafka.consumer:type=consumer-fetch-manager-metrics,client-id="{client-id}",topic="{topic}"

該指標可以直觀反映 Consumer 的整體狀況。接近零值的獲取率表明 Consumer 存在問題。如果出現指標下降,則可能是 Consumer 消費訊息失敗。

相關指標可以參考 Kafka 官方文件,指標名稱、指標定義、Mean name 在實際操作過程中以文件中最新版本為準。

搭建相關監控體系

通過自建 Prometheus 進行監控

這裡不對開源 Prometheus 搭建流程進行闡述(雖然相對繁雜,但技術社群有保姆級教程,可自行百度)。這裡只簡單介紹相關的 Kafka Exporter,當前最新版本是 v1.4.2 ,釋出於 2021.09.16 。最近一次更新是 3 個月前,關於 kafka_exporter.go 的。

但如果你跟我一樣遇到了以下一個或多個場景:

  • 初級水平,自己搞不定開源 Prometheus 部署;
  • 比較懶,又不想日常維護 Prometheus 系統,包括相關元件更新、系統整體擴容;
  • 業務上線非常著急,需要馬上有相應的監控系統;
  • 企業級使用者 希望 Prometheus 服務低成本、資料庫規模無上限、高效能高可用

那麼,阿里雲 Prometheus 監控服務是一個最佳選擇,不用再考慮以上問題,真正做到開箱即用,一鍵整合。

通過阿里雲 Prometheus 監控進行監控

登入 Prometheus 控制檯。在頁面左上角選擇目標地域,然後根據需要單擊容器服務、Kubernetes 或者 ECS 型別的 Prometheus 例項名稱。在左側導航欄單擊元件監控。

  • 新增 Kafka 型別的元件

  • 在元件監控頁面,單擊右上角的新增元件監控。在接入中心面板中單擊 Kafka 元件圖示。在接入 Kafka 面板 STEP2 區域的配置頁籤輸入各項引數,並單擊確定。在接入 Kafka 面板 STEP2 區域的指標頁籤可檢視監控指標。

4.png

5.png

  • 預設採集相關指標

6.png

  • 檢視相關資料指標

在元件監控頁面,會顯示已接入的元件例項。單擊該元件例項大盤列的大盤,檢視該元件監控指標資料。通過 Grafana 進行更全面的資料展示。

6(1).png

7.png

8.png

9.png

10.png

如果是購買 Kafka 雲產品,可以通過”Prometheus for 雲服務“進行監控

登入 Prometheus 控制檯。在頁面左上角選擇目標地域,然後選擇新建 Prometheus 例項。在彈出頁面單擊 Prometheus 例項 for 雲服務。

11.png

  • 新增 Alibaba Cloud Kafka 監控

在彈出頁面選中新增 Alibaba Cloud Kafka,然後點選確定按鈕開啟 Kafka 雲產品監控。

12.png

  • 預設採集相關指標

13.png

  • 檢視相關資料指標

在 Prometheus 雲監控詳情大盤列表頁面,會顯示已接入的 Kafka。單擊該元件例項大盤列的 CMS-KAFKA 大盤,檢視該元件監控指標資料。通過 Grafana 進行更全面的資料展示。

14.png

15.png

16.png

相較於開源 Prometheus,阿里雲 Prometheus 監控具備以下特性

17.png

參考及引用:

Kafka 官方文件:

https://kafka.apache.org/documentation/#monitoring

Kafka Exporter Github 地址:

https://github.com/danielqsj/kafka_exporter

https://zhuanlan.zhihu.com/p/473163768 https://github.com/apache/kafka https://kafka.apache.org/code.html