目錄
- Kafka監控與告警
- 1 解決方案
- 1.2 基礎知識
- JMX
- 監控指標代理
- 查看KafkaJMX遠程端口
- 1.3 真實案例
- Kafka Exporter:
- Promethus
- Promethus Alert Manager
- Grafana
- 1.3 實際操作部署監控和告警系統
- 1.2.1 部署Kafka Exporter
- 1.2.2 部署Prometheus
- 1.2.3 部署AlertManger
- 1.2.4 添加告警規則
- 1.2.5 修改告警接收配置
- 1.2.6 部署Grafana
- 2 監控指標詳解
- 1.1 按指標的來源分類
- 2.1.1 應用程序指標
- 2.1.2 日志
- 2.1.3 基礎設施指標
- 2.1.4 外部工具指標
- 2.1.5 客戶端指標
- 2.2 按指標的目的分類
- 2.2.1 用于告警
- 2.2.2 用于調試
- 2.2.3 歷史數據
- 2.3 按使用者分類
- 2.3.1 自動化系統
- 2.3.2 人
- 2.4 應用程序健康檢查
- 2.5 服務級別目標
- 服務級別定義
- 2.6 Broker的指標
- 2.6.1 如何診斷集群問題
- 2.6.2 非同步分區問題
- 2.6.2.1 集群負載不均衡
- 2.6.2.2 請求數量超過了broker的處理能力
- 2.6.2.3 主機級別的問題
- 2.6.3 Broker指標
- 活躍控制器數量
- 控制器隊列大小
- 請求處理器空閑率
- 主題流入字節
- 主題流出字節
- 主題流入消息
- 分區數量
- 首領數量
- 離線分區數量
- 請求指標
- 2.6.4 主題指標和分區指標
- 個體主題指標
- 個體分區指標
- 2.6.5 Java虛擬機監控
- 垃圾回收
- Java操作系統監控
- 2.6.6 操作系統監控
- CPU
- 磁盤
- 網絡
- 2.6.7 日志
- 2.7 客戶端監控
- 2.7.1 生產者指標
- 生產者整體指標
- 個體broker指標和個體主題指標
- 2.7.2 消費者指標
- 獲取請求管理器指標
- 個體broker指標和個體主題指標
- 消費者協調器指標
- 2.7.3 配額
- 2.8 滯后監控
- 2.9 端到端監控
- 附錄
- 1 JMX
- 1.1 什么是JMX
- 1.2 JMX的架構
- 資源探測(Instrumentation)
- 代理(Agent)
- 遠程管理(Remote Management)
- 1.2 示例代碼
Kafka監控與告警
Kafka中的監控和警報至關重要,原因如下:
- 主動問題檢測
監控有助于實時檢測Kafka集群中的問題或異常。通過根據預定義的閾值或條件設置警報,您可以在潛在問題升級并影響系統性能或可用性之前主動識別這些問題。 - 對事件的快速響應
警報使您能夠在滿足某些預定義條件時接收通知,例如高消費延遲、代理故障或復制分區不足。這使您能夠快速響應事件,調查根本原因,并采取糾正措施,最大限度地減少停機時間和數據丟失。 - 維護服務級別協議(SLA)
監控和警報有助于確保Kafka集群在性能、可用性和可靠性方面符合定義的服務級別協議。通過監控關鍵指標并設置違反SLA的警報,您可以采取主動措施來維持所需的服務級別。 - 容量規劃和資源優化
基于資源利用率指標的警報有助于容量規劃和優化資源。通過接收有關資源限制或即將出現的容量問題的警報,您可以主動擴展集群,以處理增加的工作負載并避免性能下降。 - 安全事件響應
警報對于檢測和響應Kafka中的安全事件至關重要,例如未經授權的訪問嘗試、異常用戶行為或潛在的安全漏洞。通過設置與安全相關的警報,您可以快速識別和減輕安全威脅,以保護您的Kafka數據。
總之,Kafka監控和警報對于維護Kafka集群的運行狀況、性能和安全性至關重要,能夠實現主動的問題檢測、快速的事件響應和遵守SLA。
1 解決方案
1.2 基礎知識
Kafka提供了大量的指標,監控和告警要做的就是按照需求查詢需要的指標,給針對指標指定閾值,當指標的值超出閾值時發送告警通知。所有指標都可以通過Java 管理擴展(Java management extension,JMX)接口訪問。
JMX
JMX(Java Management Extensions)是Java平臺上的一種管理和監控技術,它允許開發人員在運行時管理和監控Java應用程序。通過JMX,開發人員可以暴露應用程序中的各種信息和操作,例如性能指標、配置信息和操作方法,然后可以通過JMX客戶端進行訪問和控制。
詳情參考附錄:什么是JMX
監控指標代理
要在外部監控系統中使用這些指標,最簡單的方法是將監控系統中負責收集指標的代理連接到Kafka上。
代理可以是:
- 運行在監控系統中的一個獨立進程,并用Nagios XIcheck_jmx插件或jmxtrans連接到Kafka的JMX接口上。
- 也可以直接在Kafka中運行一個JMX代理,然后通過HTTP連接(比如Jolokia或MX4J)獲取指標。
查看KafkaJMX遠程端口
JMX端口是broker配置信息的一部分,保存在ZooKeeper中,如果監控系統要直接連到Kafka的JMX端口,那么可以先從ZooKeeper獲取端口信息。出于安全方面的考慮,Kafka默認禁用了遠程JMX。這是因為JMX不僅可以作為查看應用程序狀態的窗口,它還允許執行代碼。強烈建議使用嵌入應用程序中的JMX指標代理。
zkCli.sh get /brokers/ids/0
可以看到返回的結果,jmx端口是-1,也就是沒有開啟遠程JMX連接。
{"features": {},"listener_security_protocol_map": {"PLAINTEXT": "PLAINTEXT"},"endpoints": ["PLAINTEXT://172.26.143.96:9092"],"jmx_port": -1,"port": 9092,"host": "172.26.143.96","version": 5,"timestamp": "1716079501534"
}
如果要啟用它,則必須保護好端口。
使用如下命令啟動Kafka可以開啟遠程JMX。
JMX_PORT=19092 $KAFKA_CLUSTER_HOME/kafka-1/bin/kafka-server-start.sh $KAFKA_CLUSTER_HOME/kafka-1/config/server.properties
可以看到JMX端口已經賦值了:
{"features": {},"listener_security_protocol_map": {"PLAINTEXT": "PLAINTEXT"},"endpoints": ["PLAINTEXT://172.26.143.96:9092"],"jmx_port": 19092,"port": 9092,"host": "172.26.143.96","version": 5,"timestamp": "1716099839130"
}
如果你所仕的組織沒有監控Java應用程序的經驗,那么可以考愿使用第三方提供的監控服務。很多第三方供應商的服務包已經包含了監控代理、指標收集點、存儲、圖形可視化和告警。它們還能進一步幫你搭建符合要求的監控代理。
1.3 真實案例
下面是一個典型的Kafka監控與告警解決方案,利用了第三方開源的工具,筆者公司也使用了相似的方案。
使用的核心系統有:
Kafka Exporter:
Kafka Exporter 是一個用于監控 Apache Kafka 集群的工具,它可以將 Kafka 集群的指標導出到 Prometheus 監控系統中。通過使用 Kafka Exporter,用戶可以實時監控 Kafka 集群的健康狀況、消息流量等指標。
Kafka Exporter 的主要功能包括:
- 導出 Kafka 集群的指標到 Prometheus 格式
- 支持多個 Kafka 集群的監控
- 提供豐富的指標,包括消息生產與消費速率、分區偏移量、副本狀態等
官網鏈接:https://github.com/danielqsj/kafka_exporter/blob/master/README.md
Promethus
Prometheus 是一個開源的系統監控和警報工具包。它最初由SoundCloud開發,并于2012年在Cloud Native Computing Foundation下發布。Prometheus可以收集、存儲和查詢各種指標,并提供強大的查詢語言和靈活的警報機制。Prometheus主要用于對基礎設施的監控,幾乎所有東西都可以通過Prometheus進行監控。
官網鏈接:https://prometheus.io/docs/introduction/overview/
來自官網的架構圖:
Promethus Alert Manager
Prometheus Alertmanager是一個用于處理和路由警報的組件,它與Prometheus緊密集成。Alertmanager可以接收來自Prometheus的警報,并根據配置的規則對這些警報進行處理、路由和通知。
Alertmanager具有以下主要功能:
- 警報路由:Alertmanager可以根據配置的路由規則將警報路由到不同的接收端,如Email、Slack、PagerDuty等。
- 抑制重復警報:Alertmanager可以抑制重復的警報,以避免發送多個相同的警報通知。
- 靜默期:Alertmanager支持設置靜默期,以在某些情況下暫時屏蔽警報的發送。
- 集成第三方服務:Alertmanager可以與各種第三方服務集成,以實現更靈活的警報通知機制。
官網鏈接:https://prometheus.io/docs/alerting/latest/alertmanager/
Grafana
Grafana 是一個流行的開源數據可視化工具,它提供了豐富的圖表和面板,可以幫助用戶輕松地創建、編輯和共享儀表盤,展示各種數據源的實時監控和分析結果。Grafana 支持多種數據源,包括 Prometheus、InfluxDB、Elasticsearch、MySQL 等,用戶可以將這些數據源連接到 Grafana 中,并通過配置靈活的查詢語言來展示數據。
Grafana 的主要特點包括:
- 可視化豐富:Grafana 提供了多種圖表和面板類型,包括折線圖、柱狀圖、熱力圖等,用戶可以根據需求自定義展示數據的方式。
- 多數據源支持:Grafana 支持多種數據源,用戶可以輕松地連接不同類型的數據源,并在同一個儀表盤中展示多個數據源的數據。
- 儀表盤共享:用戶可以創建自定義的儀表盤,并將其共享給團隊成員或其他用戶,以便實時監控和共享數據分析結果。
- 警報功能:Grafana 還提供了警報功能,用戶可以設置警報規則,并在觸發條件時發送通知。
官網鏈接:https://grafana.com/grafana/dashboards
1.3 實際操作部署監控和告警系統
下面就具體的部署步驟來進行簡單的演示。
1.2.1 部署Kafka Exporter
安裝包下載地址:https://github.com/danielqsj/kafka_exporter/releases
依次運行命令:
# 下載安裝包
wget https://github.com/danielqsj/kafka_exporter/releases/download/v1.7.0/kafka_exporter-1.7.0.linux-amd64.tar.gz
# 解壓縮
sudo tar -xzvf kafka_exporter-1.7.0.linux-amd64.tar.gz -C /usr/local/bin
# 賦權限
sudo chmod -R 777 /usr/local/bin/kafka_exporter-1.7.0.linux-amd64
ls -l /usr/local/bin/kafka_exporter-1.7.0.linux-amd64
# 啟動
/usr/local/bin/kafka_exporter-1.7.0.linux-amd64/kafka_exporter --kafka.server=172.26.143.96:9091 --kafka.server=172.26.143.96:9092 --kafka.server=172.26.143.96:9093
如果能成功訪問地址:http://172.26.143.96:9308/metrics,看到Kafka的度量指標,說明安裝成功。
1.2.2 部署Prometheus
官網下載地址:https://prometheus.io/download/#prometheus
依次運行命令:
wget https://github.com/prometheus/prometheus/releases/download/v2.52.0/prometheus-2.52.0.linux-amd64.tar.gz
sudo tar -xzvf prometheus-2.52.0.linux-amd64.tar.gz -C /usr/local/bin
sudo chmod -R 777 /usr/local/bin/prometheus-2.52.0.linux-amd64
ls -l /usr/local/bin/prometheus-2.52.0.linux-amd64
編輯Prometheus的配置文件:
vim /usr/local/bin/prometheus-2.52.0.linux-amd64/prometheus.yml
修改監控指標來源為Kafka_export的地址:“172.26.143.96:9308”
scrape_configs:# The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.- job_name: "prometheus"# metrics_path defaults to '/metrics'# scheme defaults to 'http'.static_configs:- targets: ["172.26.143.96:9308"]
最后啟動Prometheus:
/usr/local/bin/prometheus-2.52.0.linux-amd64/prometheus --config.file=/usr/local/bin/prometheus-2.52.0.linux-amd64/prometheus.yml
如果能成功訪問地址:http://172.26.143.96:9090/targets,說明部署成功
1.2.3 部署AlertManger
官網下載地址:https://prometheus.io/download/#alertmanager
依次運行命令:
wget https://github.com/prometheus/alertmanager/releases/download/v0.27.0/alertmanager-0.27.0.linux-amd64.tar.gz
sudo tar -xzvf alertmanager-0.27.0.linux-amd64.tar.gz -C /usr/local/bin
sudo chmod -R 777 /usr/local/bin/alertmanager-0.27.0.linux-amd64
ls -l /usr/local/bin/alertmanager-0.27.0.linux-amd64
集群模式啟動
/usr/local/bin/alertmanager-0.27.0.linux-amd64/alertmanager --config.file=/usr/local/bin/alertmanager-0.27.0.linux-amd64/alertmanager.yml --web.listen-address=172.26.143.96:9095 --cluster.listen-address=:9096
單機模式啟動:
/usr/local/bin/alertmanager-0.27.0.linux-amd64/alertmanager --config.file=/usr/local/bin/alertmanager-0.27.0.linux-amd64/alertmanager.yml --web.listen-address=172.26.143.96:9095 --cluster.listen-address=\
如果能成功訪問地址:http://172.26.143.96:9095/#/alerts,說明部署成功。
1.2.4 添加告警規則
在Prometheus的安裝目錄下創建該井規則文件:
/usr/local/bin/prometheus-2.52.0.linux-amd64/kafka_alert_rules.yml
groups:
- name: kafka-alertsrules:- alert: KafkaBrokerDownexpr: kafka_brokers < 4for: 1mlabels:severity: errorannotations:summary: "The number of brokers {{$value}} of cluser {{$labels.env}} is less than 4."description: "Brokers's number is less than 4."
然后修改配置文件并重啟Prometheus:
# Alertmanager configuration
alerting:alertmanagers:- static_configs:- targets:- 172.26.143.96:9095# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:# - "first_rules.yml"# - "second_rules.yml"- "kafka_alert_rules.yml"
1.2.5 修改告警接收配置
修改AlertManager配置文件,將webhook地址配置成要接受告警的服務地址。
vim /usr/local/bin/alertmanager-0.27.0.linux-amd64/alertmanager.yml
route:group_by: ['alertname']group_wait: 30sgroup_interval: 5mrepeat_interval: 1hreceiver: 'web.hook'
receivers:- name: 'web.hook'webhook_configs:- url: 'http://127.0.0.1:5001/kafka/alerts'
inhibit_rules:- source_match:severity: 'critical'target_match:severity: 'warning'equal: ['alertname', 'dev', 'instance']
1.2.6 部署Grafana
官網下載地址:https://grafana.com/grafana/download?pg=graf&plcmt=deploy-box-1
依次運行命令:
wget https://dl.grafana.com/enterprise/release/grafana-enterprise-11.0.0.linux-amd64.tar.gz
sudo tar -zxvf grafana-enterprise-11.0.0.linux-amd64.tar.gz -C /usr/local/bin
sudo chmod -R 777 /usr/local/bin/grafana-v11.0.0
ls -l /usr/local/bin/grafana-v11.0.0
復制配置文件并啟動:
cp /usr/local/bin/grafana-v11.0.0/conf/sample.ini /usr/local/bin/grafana-v11.0.0/conf/grafana.ini
/usr/local/bin/grafana-v11.0.0/bin/grafana server -homepath /usr/local/bin/grafana-v11.0.0 -config /usr/local/bin/grafana-v11.0.0/conf/grafana.ini
官網鏈接https://grafana.com/docs/grafana/latest/setup-grafana/start-restart-grafana/
如果能成功訪問地址:http://172.26.143.96:3000,說明部署成功。
接下來還需要配置Prometheus的dashboard:
- 在左側菜單選擇添加數據源
填入Prometheus的地址:http://172.26.143.96:9095。
官網鏈接:https://grafana.com/docs/grafana/latest/datasources/prometheus/configure-prometheus-data-source/ - 導入dashboard
可以導入現成的dashboard模板,就不用自己創建了。我導入了編號7589的模板。 - 訪問dashbaord鏈接
http://172.26.143.96:3000/d/jwPKIsniz/kafka-exporter-overview?orgId=1
2 監控指標詳解
1.1 按指標的來源分類
并不是所有的指標都來自Kafka,我們能夠獲取到的指標通常可以分為5類。
2.1.1 應用程序指標
這些是可以通過JMX接口獲取到的Kafka 指標。
2.1.2 日志
來自Kafka的另一種監控數據。因為日志是文本或結構化數據,不僅僅是數字,所以需要進行額外的處理。
2.1.3 基礎設施指標
這些指標來自部署在Kafka前面的系統,這些系統也處在請求路徑中,并在你的可控范
圍之內,比如負載均衡器就屬于這一類。
2.1.4 外部工具指標
這些數據來自Kafka以外的工具,類似于客戶端,但在你的直接控制之下,它們的用途
與普通的Kafka客戶端不一樣,比如Kafka健康檢查就屬于這一類。
2.1.5 客戶端指標
這些指標來自與集群相連的Kafka客戶端。
2.2 按指標的目的分類
2.2.1 用于告警
用于告警的指標在短時間內(通常不會比對問題做出響應所需的時間長很多)非常有用。可以以小時或天為單位,將這些指標發送給能夠對已知問題做出響應的自動化工具,或者沒有自動化工具,則可以發送給運維人員。
2.2.2 用于調試
用于調試問題的數據需要保留較長的時間,因為你可能會頻繁診斷已經存在一段時間的問題或對比較復雜的問題進行更深入的探究。這些數據在被收集到之后需要保留幾天或幾周,它們通常比較客觀,或者是來自Kafka應用程序本身。
需要注意的是,并不一定要將這些數據收集到監控系統中。如果主要目的是調試問題,那么在調試問題時能夠獲取它們就可以了。不需要持續不斷地收集數以萬計的指標,從而讓監控系統不堪重負。
2.2.3 歷史數據
你可能還需要第三種類型的數據,也就是應用程序的歷史數據。通常,歷史
數據被用于容量管理,它們一般會包含資源的使用信息,比如計算資源、存
儲和網絡。這些指標需要保存很長一段時間,一般以年為單位。你可能還需
要收集額外的元數據,比如一個broker是何時加入或被移出集群的,這些元
數據將作為指標的上下文信息。
2.3 按使用者分類
2.3.1 自動化系統
如果指標被用在自動化系統中,那么它們就應該非常具體。我們可以收集大量的指標,并且每個指標都只描述一些小細節,這沒有問題,因為這就是計算機存在的原因:處理大量的數據。指標越具體,就越容易對其進行自動化,因為越具體就越沒有太多的解釋空間。
2.3.2 人
如果指標是給人類看的,那么太多的指標會讓人類不堪重負。在基于指標定義告警時,這一點尤為重要。人們很容易陷入“告警疲勞”,因為告警太多,很難知道問題究竟有多嚴重。我們也很難為每個指標定義合理的閾值并持續更新它們。如果告警過多或經常誤報,我們就會懷疑告警是否正確地反映了應用程序的狀態。
2.4 應用程序健康檢查
需要用簡單的方式來監控應用的整體健康狀況:
- 使用外部進程來報告 broker的運行狀態(健康檢測)。
例如有一個定時任務每分鐘向broker寫入消息并成功讀取。 - 在broker停止發送指標時發出告警(有時也叫作過時指標)。
雖然第二種方式也是可行的,但有時候很難區分是broker出了問題還是監控系統本身出了問題。
2.5 服務級別目標
對基礎設施服務(如Kafka)來說,**服務級別目標(service level objective,SLO)**是一個非常重要的監控領域。服務供應商可以基于這些指標向客戶宣稱他們能夠獲得怎樣的基礎設施服務級別。
服務級別定義
在討論Kafka的SLO之前,需要先統一一下涉及的術語。你可能經常聽到工程師、經理、高管等錯誤地使用“服務級別”這個術語,導致人們對他們正在談論的東西困惑重重。
服務級別指標(service level indicator,SLI) 是一種用于描述服務可靠性的指標。因為它與用戶體驗緊密相關,所以通常來說越客觀越好。在一個處理請求的系統(如Kafka)中,這個指標通常用正常事件數量與總事件數量之間的比率來表示,比如Web服務器在處理請求時返回2xx、3xx或4xx響應的比例。
服務級別目標(SLO)也叫作服務級別閾值(service level threshold,SLT) 它將SLI與目標值組合在一起。服務級別目標的一種常見表示方法是使用數字9(99.9%就是39),盡管這不是必需的。SLO還需要包含一個時間窗口,通常以天為單位。例如,7天內99%發送給Web服務器的請求必須返回一個2xx、3xx或4xx響應。
服務級別協議(service level agreement,SLA) 是服務供應商和客戶之間的一種契約。它通常會包含幾個SLO,以及如何度量和報告它們、客戶如何向服務供應商尋求支持、服務供應商如果不按照SLA執行將受到怎樣的懲罰。例如,之前的SLO所對應的SLA可能是這樣的:如果服務供應商在SLO服務期內暫停運營,那么就需要退還客戶為此期間支付的所有費用。
哪些指標是好的SLI
通常,需要使用外部工具或系統來收集適用于SLI的指標。SLO可以用來描述你服務的田戶的滿意度,我們無法主觀地得出這些指標。客戶并不關心你是否認為你的服務運行正滑他們的體驗才是關鍵。也就是說,基礎設施指標沒什么問題,外部工具指標也不錯,但客戶端指標可能是大多數SLI的最佳指標。
在請求響應和數據存儲系統中常見的SLI:
- 可用性
- 延遲
- 質量
- 安全性
- 吞吐量
將SLO用于告警
SLO應該為你提供主要的告警。因為SLO是從客戶的角度描述問題,而這些問題應該是首先要關注的。一般來說,如果一個問題不會對你的客戶造成影響,就不會重要到要在以里把你叫醒的程度。SLO還會告訴你一些你不知道該如何檢測的問題,因為你以前可能從未遇到過。
問題在于,我們很難直接將SLO作為告警。SLO的時間范圍通常較長(比如一周),因為
我們希望提供給高層或客戶的SLO是可重復查看的。此外,在發出SLO告警時,可能已經太遲了,因為你已經在SLO之外采取了行動。
有些人用派生值來設置預警,但在告警中使用SLO的最佳方式是觀察SLO的燃燒率。
2.6 Broker的指標
broker提供了很多指標。它們大部分是底層的度量信息,是Kafka開發者為診斷特定問題或預計在未來調試問題時需要用到這些信息而添加的。broker的每一項功能都有相應的指標,其中一些最為常見的指標為Kafka的日常運行提供了必要的信息。
2.6.1 如何診斷集群問題
Kafka集群一般會出現3類問題。
- 單個broker的問題
這些問題會通過異常的集群指標易現出來,通常與緩便或發生故障的存儲設備或者計算資源限制有關。要檢測這些問題,需要根據操作系統的指標監控每個服務器的可用性和存儲設備的運行狀態。
加果問題不在操作系統或硬件層面,那么很可能是Kafka集群負載不均衡導致的。盡管Kafka盡量保持集樣數據能夠均勻地分布在所有的broker上,但并不能保證訪問這些數據的客戶端是均勻分布的。Kafka也無法檢測出諸如熱分區之類的問題。強烈建議使用外部工具來保持集群均衡,比如Cruise Control,它會持續監控集群,并在集群不均衡時對分區進行再均衡。它還提供了很多其他的管理功能,比如添加和刪除broker。 - 集群過載
集群過載也是一個很容易檢測的問題。如果集群是均衡的,并且多個broker的請求延遲一直在增加或者請求處理器空閑率較低,那么說明集群broker處理流量的能力達到了極限。你可能會發現一個客戶端改變了它的請求模式,正在給你的集群制造麻煩。但即使發生了這種情況,你可能也無法對客戶端做些什么。你能做的要么是降低集群負載,要么是增加broker。 - 控制器的問題
集群控制器的問題較難診斷,它們通常屬于Kafka本身的bug。這些問題表現為broker元數據不同步、broker看起來正常但副本是離線的,以及主題操作問題(比如創建主題的操作沒能被正常執行)。如果一個集群問題讓你抓狂,讓你不禁覺得“這真的很奇怪”,那么很有可能是因為控制器做了一些不可預知的事情。監控控制器的方法并不多,不過,只要監控好活動控制器的計數和控制器隊列大小,當出現問題時,它們也是很有用的。
2.6.2 非同步分區問題
非同步分區是最為常見的監控指標:
指標名稱 | JMX MBean | 取值范圍 |
---|---|---|
非同步分區數 | kafka.server: type=ReplicaManager,name=UnderReplicatedPartitionis | 非負整數 |
如果集群中多個broker的非同步分區數量一直很穩定(保持不變),則說明集群中的某
個broker已經離線了。整個集群的非同步分區數量等于離線broker的分區數量,而離線broker不會生成任何指標。在這種情況下,需要檢查這個broker出了什么問題,并解決問題。通常可能是硬件問題,也可能是操作系統問題或Java的問題。
2.6.2.1 集群負載不均衡
需要用到以下幾個指標:
- 分區數量
- 首領分區數量
- 所有主題的消息流入速率
- 所有主題的字節流入速率
- 所有主題的字節流出速率
在一個均衡的集群中,這些指標的數值在整個集群范圍內是均衡的。要解決這個問題,需要將負載較重的broker分區移動到負載較輕的broker上,這可以使用kafka-reassign-partitions.sh來實現。
2.6.2.2 請求數量超過了broker的處理能力
Kafka集群的另一個性能問題是請求數量超過了broker的處理能力。有很多潛在的瓶頸會地慢整個集群:CPU、磁盤IO和網絡吞吐量是其中最為常見的。磁盤使用率不在其列,因內broker會一直運行,直到磁盤被填滿然后“掛掉”。為了診斷這類問題,可以監控以下這些操作系統級別的指標。
- CPU使用
- 網絡輸入吞吐量
- 網絡輸出吞吐量
- 磁盤平均等待時間
- 磁盤使用百分比
上述任何一種資源出現過度消耗都會表現為分區不同步。
2.6.2.3 主機級別的問題
如果性能問題不是出現在集群級別,而是出現在一兩個broker中,就要檢查一下broker所在的主機,看看是什么導致它與集群中的其他broker不一樣。主機級別的問題可以分為以下幾類。
· 硬件故障
· 網絡
· 進程沖突
· 本地配置不一致
2.6.3 Broker指標
活躍控制器數量
指標名稱 | JMX MBean | 取值范圍 |
---|---|---|
活躍控制器數量 | kafka.controller: type=KafkaController,name=ActiveControllerCount | 0或1 |
如果集群中沒有控制器,就無法對狀態變化(比如創建主題或分區或者broker故障)做出正確的響應。這個時候,要仔細檢查為什么控制器線程出現了異常。例如,ZooKeeper集群的網絡分區就會導致這個問題。在解決了這些底層問題之后,最好重啟所有的broker,以便重置控制器線程的狀態。
控制器隊列大小
指標名稱 | JMX MBean | 取值范圍 |
---|---|---|
控制器隊列大小 | kafka.controller:type=ControllerEventManager,name=EventQueueSize | 非負整數 |
控制器隊列大小指標會告訴我們控制器當前有多少個等待處理的請求,它的值可以是0或正整數。因為新請求不斷在涌入,管理操作(比如創建分區、移動分區和首領變更)也不斷在發生,所以這個指標的值會頻繁波動。這個指標會出現可預料的峰值,但如果持續增長,或保持在一個較高的位置不下降,則說明控制器可能被卡住了。這可能導致管理任務無法被正常執行。要解決這個問題,需要關閉當前的控制器,并將控制器角色交給另一個broker。但是,當控制器被卡住時,我們無法通過正常的方式關閉它。
請求處理器空閑率
指標名稱 | JMX MBean | 取值范圍 |
---|---|---|
請求處理器空閑率 | kafka.server:type=KafkaRequestHandlerPool,name=RequestHandlerAvgIdlePercent | 從0到1的浮點數(包括1在內) |
Kafka 使用兩個線程池來處理客戶端請求:網絡線程和請求處理線程(也叫IO線程)。網絡線程負責通過網絡讀入數據和寫出數據。這里不涉及太多的處理工作,所以不用太過擔心這些線程會被耗盡。請求處理線程負責處理來自客戶端的請求,包括從磁盤讀取消息和向磁盤寫入消息。因此,broker負載的增長對這個線程池有很大的影響。
這個指標值越低,說明系統負載越高。如果空閑百分比低于20%,那么說明存在潛在的問題;如果低于10%,則說明出現了性能問題。
除了集群的規模太小,還有其他兩個方面的原因會導致這個線程池被重度使用。
- 線程池里設有足夠的線程。一般來說,請求處理線程的數量應該等于系統的處理器核數(包括多線程處理器)。
- 線程做了不該做的事。
主題流入字節
指標名稱 | JMX MBean | 取值范圍 |
---|---|---|
每秒流入字節 | kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec | 速率為雙精度浮點數,計數為整數 |
主題流入字節速率使用字節/秒來表示,用于度量broker從生產者客戶端接收到的消息流量。可以基于這個指標決定何時對集群進行擴展或開展其他與流量增長相關的工作。這個指標也可用于評估一個broker是否比集群中的其他broker接收了更多的流量,如果出現了這種情況,則需要對分區進行再均衡。
所有的速率指標都有7個屬性,使用哪些屬性取決于你想獲得哪方面的信息。有些屬性是離散的事件計數,有些是基于時間段的事件平均數。務必在合適的地方使用合適的指標,否則你將得到一個錯誤的broker視圖。
屬性名稱 | 解釋 | |
---|---|---|
1 | EventType | 速率屬性的度量單位,在這里是“字節”。 |
2 | RateUnit | 速率的時間段,在這里是“秒”。這兩個屬性表明,速率是通過字節/秒來表示的,不管它的值是基于多長時間段計算出來的平均值。速率還有其他4個不同粒度的屬性。 |
3 | OneMinuteRate | 前1分鐘的平均值。 |
4 | FiveMinuteRate | 前5分鐘的平均值。 |
5 | FifteenMinuteRate | 前15分鐘的平均值。 |
6 | MeanRate | 從 broker啟動到現在的平均值。 |
7 | Count | 除了速率屬性,速率指標還有一個Count屬性,它在broker啟動之后就一直保持增長。Count表示從broker啟動以來接收的流量的字節總數。將這個屬性用在一個支持計數指標的監控系統中,就可以獲得完整的度量視圖(我們看到的不僅僅是平均速率)。 |
主題流出字節
指標名稱 | JMX MBean | 取值范圍 |
---|---|---|
每秒流出字節 | kafka.server: type=BrokerTopicMetrics,name=BytesOutPerSec | 速率為雙精度浮點數,計數為整數 |
主題流出字節速率是另一個與流量增長有關的指標,與流入字節速率類似。流出字節速率也就是消費者從broker讀取消息的速率。流出速率的擴展方式與流入速率不一樣。這是因為Kafka支持多消費者客戶端。很多Kafka集群的流出速率可以達到流入速率的6倍!這就是為什么要單獨對流出速率進行觀察和分析。表
主題流入消息
指標名稱 | JMX MBean | 取值范圍 |
---|---|---|
每秒流入消息 | kafka.server: type=BrokerTopicMetrics, name=MessagesInPerSec | 速率為雙精度浮點數,計數為整數 |
前面介紹的字節速率使用字節來表示broker流量,而消息速率則使用每秒生成消息條數(不考慮消息的大小)來表示流量。這也是一個很有用的生產者流量增長指標。它還可以與字節速率結合在一起使用,用于計算消息的平均大小。與字節速率一樣,這個指標也能反映出集群流量是否均衡。
為什么沒有消息流出速率?
這是因為在消息被讀取時,broker會將整個消息批次發送給消費者,并不會展開計算每個批次包含了多少條消息。所以,broker也就不知道發送了多少條消息。broker提供了一個每秒獲取請求次數指標,不過它是一種請求速率,不是消息計數。
分區數量
指標名稱 | JMX MBean | 取值范圍 |
---|---|---|
分區數量 | kafka.server: type=ReplicaManager,name=PartitionCount | 非負整數 |
broker的分區數重就是分配給broker的分區總數,一般不會經常發生變化。它包括broker的每一個分區副本,不管是首領副本還是跟隨者副本。如果一個集群啟用了自動創建士顧的功能,那么監控這個指標就會很有趣,因為主題的創建不受集群管理員的控制。
首領數量
指標名稱 | JMX MBean | 取值范圍 |
---|---|---|
首領數量 | kafka.server:type=ReplicaManager,name=LeaderCount | 非負整數 |
首領數量指標表示一個broker的首領分區數量。與broker的其他指標一樣,這個指標也應該在整個集群的broker之間保持均衡。我們需要定期檢查這個指標,并適時地發出告警,因為即使在副本的數量和大小看起來都很均衡的時候,它仍然能夠顯示出集群的不均衡。broker有可能會因為各種原因釋放掉一個分區的領導權(比如ZooKeeper會話過期),但在會話恢復之后并不會自動收回領導權(除非啟用了自動首領再均衡)。在這些情況下,這個指標會顯示較少的首領分區數,或通常為零。這時候需要進行一次首選副本選舉,重新均衡集群的首領。
可以將這個指標與分區數量指標結合在一起,計算出以該broker作為首領的分區的百分比。一個均衡的集群,如果它的復制系數是2,那么所有的broker都應該差不多是50%分區的首領。如果復制系數是3,則這個百分比應該降到33%。
離線分區數量
指標名稱 | JMX MBean | 取值范圍 |
---|---|---|
離線分區數量 | kafka.controller:type=KafkaController,name=OfflinePartitonsCount | 非負整數 |
與非同步分區數量一樣,離線分區數量也是一個關鍵的監控指標。只有集樣控制器會提供這個指標(其他broker提供的值為零),它會告訴我們集群中有多少個分區是沒有首領的。
以下兩個原因會導致分區沒有首領:
- 包含這個分區副本的所有broker都關閉了。
- 由于消息數量不匹配,沒有同步副本能夠獲得領導權(并禁用了不徹底首領選舉)。
在生產環境中,離線分區會影響生產者客戶端,導致消息丟失或應用程序回壓。這屬于“站點停機”問題,需要立即解決。
請求指標
Kafka協議,它有多種請求,每種請求都有相應的指標。
AddOffsetsToTxn | AddPartitionsToTxn | AlterConfigs |
AlterPartitionReassignments | AlterReplicaLogDirs | ApiVersions |
ControlledShutdown | CreateAcls | CreateDelegationToken |
CreatePartitions | CreateTopics | DeleteAcls |
DeleteGroups | DeleteRecords | DeleteTopics |
DescribeAcls | DescribeConfigs | DescribeDelegationToken |
DescribeGroups | DescribeLogDirs | ElectLeaders |
EndTxn | ExpireDelegationToken | Fetch |
FetchConsumer | FetchFollower | FindCoordinator |
Heartbeat | IncrementalAlterConfigs | InitProducerId |
JoinGroup | LeaderAndIsr | LeaveGroup |
ListGroups | ListOffsets | ListPartitionReassignments |
Metadata | OffsetCommit | OffsetDelete |
OffsetFetch | OffsetsForLeaderEpoch | Produce |
RenewDelegationToken | SaslAuthenticate | SaslHandshake |
StopReplica | SyncGroup | TxnOffsetCommit |
UpdateMetadata | WriteTxnMarkers |
每一種請求類型都有8個指標,它們分別提供了不同處理階段的細節。
名字 | JMX MBean |
---|---|
總時間 | kafka.network:type=RequestMetrics,name=TotalTimeMs,request=Fetch |
請求隊列時間 | kafka.network:type=RequestMetrics,name=RequestQueueTimeMs,request=Fetch |
本地時間 | kafka.network:type=RequestMetrics,name=LocalTimeMs,request=Fetch |
遠程時間 | kafka.network:type=RequestMetrics,name=RemoteTimeMs,request=Fetch |
節流時間 | kafka.network:type=RequestMetrics,name=ThrottleTimeMs,request=Fetch |
響應隊列時間 | kafka.network:type=RequestMetrics,name=ResponseQueueTimeMs,request=Fetch |
響應發送時間 | kafka.network:type=RequestMetrics,name=ResponseSendTimeMs,request=Fetch |
每秒請求數 | kafka.network:type=RequestMetrics,name=RequestsPerSec,request=Fetch |
什么是百分位
2.6.4 主題指標和分區指標
除了用于描述broker一般行為的指標,還有很多主題級別的指標和分區級別的指標。在較大的集群中,這樣的指標很多,一般來說不太可能將它們全部收集到一個指標系統中,但在調試與客戶端相關的問題時,它們會很有用。
個體主題指標
名字 | JMX MBean |
---|---|
字節流入速率 | kafka.server:type=BrokerTopicMetrics,name=BytesInPerSec,topic=TOPICNAME |
字節流出速率 | kafka.server:type=BrokerTopicMetrics,name=BytesOutPerSec,topic=TOPICNAME |
失敗的獲取速率 | kafka.server:type=BrokerTopicMetrics,name=FailedFetchRequestsPerSec,topic=TOPICNAME |
失敗的生產速率 | kafka.server:type=BrokerTopicMetrics,name=FailedProduceRequestsPerSec,topic=TOPICNAME |
消息流入速率 | kafka.server:type=BrokerTopicMetrics,name=MessagesInPerSec,topic=TOPICNAME |
獲取請求速率 | kafka.server:type=BrokerTopicMetrics,name=TotalFetchRequestsPerSec,topic=TOPICNAME |
生產請求速率 | kafka.server:type=BrokerTopicMetrics,name=TotalProduceRequestsPerSec,topic=TOPICNAME |
個體主題指標與前面介紹的broker指標非常相似。事實上,它們之間唯一的區別在于,個體主題指標指定了特定的主題名稱,也就是說,這些指標屬于某個特定的主題。因為個體主題指標的數量可能非常巨大(取決于集群主題的數量),所以我們極有可能不會監控它們或為它們設宜警。它們通常會被提供給客戶端,客戶端將用它們來評估和調試自己對Kafka的使用。
個體分區指標
個體分區指標不如個體主題指標有用。另外,它們的數量更加龐大,因為幾百個主題可能句含數千個分區。不過,在某些情況下,它們還是有一定用處的,特別是用于表示分區當前在磁盤上保留的數據量的分區大小指標。如果把它們組合在一起,則可以知道主題保留了多少數據。如果同一主題的兩個分區大小存在差異,則說明消息分布不均衡。日志片段數量指標表示分區保存在磁盤上的日志片段文件的數量。它可以與分區大小指標結合起來使用,用于跟蹤磁盤資源的使用情況。
名稱 | JMX MBean |
---|---|
分區大小 | kafka.log:type=Log,name=Size,topic=TOPICNAME,partition=0 |
日志片段數量 | kafka. log:type=Log,name=NumLogSegments, topic=TOPICNAME,partition=0 |
日志結束偏移量 | kafka.log:type=Log,name=LogEndOffset,topic=TOPICNAME,partition=0 |
日志起始偏移量 | kafka.log:type=Log,name=LogStartOffset,topic=TOPICNAME,partition=0 |
2.6.5 Java虛擬機監控
除了broker的指標,還需要監控服務器的指標和Java虛擬機(JVM)的指標。JVM頻繁
發生垃圾回收會影響broker的性能,這個時候應該收到告警。JVM的指標還能告訴我們為什么broker下游組件的指標會發生變化。
垃圾回收
任JM方面,最需要監控的是垃圾回收(GC)狀態。需要監控哪些MBean取決于你使用
H Java運行時(JRE)和垃圾回收器配置。如果你使用的是Oracle Java 1.8和G1垃圾回收器,G1垃圾回收指標:
名稱 | JMX MBean |
---|---|
完全垃圾回收周期 | java. lang: type=GarbageCollector,name=G1 Old Generation |
年輕代垃圾回收周期 | java. lang: type=GarbageCollector,name=G1 Young Generation |
需要注意的是,在垃圾回收語義中,“Old”和“Full”代表的是一個意思。對于上述的兩
個指標,我們需要收集CollectionCount和CollectionTime這兩個屬性。CollectionCount表示從JVM啟動開始算起的垃圾回收次數,CollectionTime表示從JVM啟動開始算起的垃圾回收時間(以毫秒為單位)。因為這些屬性都是計數值,所以它們可以告訴我們單位時間內發生垃圾回收的絕對次數和時間。還可以用它們計算出平均每次垃圾回收花費的時間,盡管這在日常運維中沒有多大用處。
這些指標還有一個LastGcInfo屬性。這是由5個屬性組成的組合值,為我們提供了最后一次垃圾回收的信息。5個屬性中最重要的一個屬性是duration(以毫秒為單位),表示最后一次垃圾回收花費了多長時間。其他幾個屬性(GcThreadCount、id、startTime和endTime)雖然也會提供一些信息,但用處不大。不過需要注意的是,我們無法通過這些屬性查看到每一次垃圾回收的信息,因為年輕代垃圾回收發生得非常頻繁。
Java操作系統監控
名稱 | JMX MBean |
---|---|
操作系統信息 | java.lang:type=OperatingSystem |
JVM通過這個MBean提供了有關操作系統的一些信息,但這些信息很有限,并不能告訴我們操作系統的所有情況。有兩個比較有用但在操作系統層面難以收集到的屬性是MaxFileDescriptorCount 和OpenFileDescriptorCount。
MaxFileDescriptorCount 告訴我們JVM最多能打開多少個文件描述符(FD),
OpenFileDescriptorCount 告訴我們目前已經打開了多少個文件描述符。每個日片段和網絡連接都需要一個文件描述符,所以它們的數量增長得很快。如果網絡連接不能被正常關閉,那么broker很快就會把文件描述符耗盡。
2.6.6 操作系統監控
JVM并不能告訴我們所有與操作系統相關的信息。因此,我們不僅要收集broker的指標,也需要收集操作系統的指標。大多數監控系統會提供代理,這些代理將收集有關操作系統的信息。我們需要收集的信息包括CPU的使用情況、內存的使用情況、磁盤的使用情況、磁盤IO和網絡的使用情況。
CPU
在CPU方面,至少需要監控系統平均負載。系統負載是一個數字,表示處理器的相對使用率。另外,按照使用類型收集到的CPU使用百分比信息也很有用。根據收集方法和操作系統的不同,我們可以得到如下這些CPU百分比細分(使用了縮寫)中的一部分或全部。
us | 用戶空間使用的時間。 |
sy | 內核空間使用的時間。 |
nt | 低優先級進程使用的時間。 |
id | 空閑時間。 |
wa | 等待(磁盤)時間。 |
hi | 處理硬件中斷的時間。 |
si | 處理軟件中斷的時間。 |
st | 等待監視器的時間。 |
什么是系統負載?
系統負載是對CPU使用情況的度量。平均負載是指等待處理器執行的可執行進程數。Linux系統中還有一些處于不可中斷睡眠狀態的進程,比如磁盤等待。負載用3個數值來表示,分別是前1分鐘的平均數、前5分鐘的平均數和前15分鐘的平均數。
- 在單CPU系統中,數值1表示系統負載達到了100%。此時總是會存在一個等待執行的進程。
- 在多CPU系統中,如果負載達到100%,那么它的數值就等于CPU核數。如果系統的CPU的核數是24,那么負載達到100%時它的數值就是24。
跟蹤broker的CPU使用情況是很有必要的,因為它們在處理請求時占用了大量的CPU
時間。內存使用情況的跟蹤就顯得沒那么重要了,因為運行Kafka并不需要太大的內存。broker會使用堆外的一小部分內存來壓縮數據,剩下的大部分會被用作緩存。盡管如此,還是要跟蹤內存的使用情況,確保broker的內存不會受到其他應用程序的影響。可以通過監控總內存空間和可用交換內存空間來確保內存交換空間沒有被其他應用程序占用。
磁盤
對Kafka來說,磁盤是最重要的子系統。所有的消息都保存在磁盤上,所以Kafka的性能很大程度上依賴于磁盤的性能。我們需要監控磁盤空間和索引節點(索引節點是Unix文件系統中文件和目錄的元數據對象),確保磁盤空間不會被用光。對保存數據的分區來說更是如此。還需要監控磁盤IO的統計數據,它們可以告訴我們磁盤是否被有效利用。至少,我門要監控磁盤的每秒讀寫速度、平均讀寫隊列大小、平均等待時間和磁盤使用百分比。
網絡
最后,還需要監控broker的網絡使用情況。簡單地說,就是流入和流出的網絡流量,一般用每秒多少位來表示。需要注意的是,在沒有消費者的情況下,流入一個位就有復制系數個位流出,如果再算上消費者,那么流出流量很容易比流入流量高出一個數量級。在設置告警閾值時要切記這一點。
2.6.7 日志
沒有日志的監控是不完整的。與其他應用程序一樣,broker也會將日志寫到磁盤上。為了能夠從日志中獲得有用的信息,需要配置恰當的日志級別。可以通過記錄INFO級別的日志捕捉到很多有關broker運行狀態的重要信息。為了獲得一系列清晰的日志文件,需要將不同的日志分開。
有兩個日志記錄器,它們會分別將日志寫到單獨的磁盤文件中。一個是kafka.controller,我們可以將它的級別設置為INFO。這個日志記錄了集群控制器的信息。在任何時候,集群中都只有一個控制器,所以只有一個broker會使用這個日志。日志中包含了主題的創建和修改操作信息、broker的狀態變更信息,以及集群活動的信息,比如首選副本選舉和分區移動。另一個是kafka.server.ClientQuotaManager,我們也可以將它的級別設置為INFO。這個日志用于記錄與生產和消費配額活動相關的信息。因為這些信息很有用,所以最好不要把它們記錄在broker的主日志文件中。
日志壓實線程的運行狀態也是有用的信息。不過,Kafka并沒有為這些線程提供單獨的指標。一個分區壓實失敗可能導致整個壓實線程崩潰,而且這是靜默發生的。可以啟用kafka.log.LogCleaner、kafka.log.Cleaner 和kafka.log.LogCleanerManager這些日志,并將它們的級別設置為DEBUG,這樣就可以輸出這些線程的運行狀態信息。這些日志包含了每個被壓實的分區的大小和消息條數。正常情況下,這些日志的數量不會很大,所以默認啟用這些日志并不會給我們造成什么麻煩。
在調試問題時,還有一些日志也很有用,比如kafka.request.logger,我們可以將它的級
別設置為DEBUG或TRACE。這個日志包含了發送給broker的每一個請求的詳細信息。如果級別被設置為DEBUG,那么它將包含連接端點、請求時間和概要信息。如果級別被設置為TRACE,那么它將包含主題和分區的信息,以及除消息體之外的所有與請求相關的信息。不管被設置成什么級別,這個日志都會產生大量的數據,所以如果不是出于調試的目的,則不建議啟用這個日志。
2.7 客戶端監控
所有的應用程序都需要被監控。Kafka客戶端,不管是生產者還是消費者,都有特定的指標需要監控。本節將主要介紹如何監控官方的Java客戶端,其他第三方客戶端應該也提供了自己的指標。
2.7.1 生產者指標
Kafka生產者客戶端的指標經過精簡只提供了少量的JMX MBean。相反,舊版本客戶端(不再受支持)提供了大量的MBean,其中有很多指標包含了更多的細節(包括大量的百分位和各種移動平均數)。它們有更大的覆蓋面,卻讓異常情況跟蹤變得更加困難。所有的生產者指標在MBean名字里都有對應的客戶端ID。
名稱 | JMX MBean |
---|---|
生產者整體 | kafka.producer:type=producer-metrics,client-id=CLIENTID |
個體 broker | kafka.producer:type=producer-node-metrics,client-id=CLIENTID,node-td=node-BROKERID |
個體主題 | kafka.producer:type=producer-topic-metrics,cltent-id=CLIENTID,topic=TOPICNAME |
上面列出的每一個MBean都提供了多個屬性用于描述生產者的狀態。下面列出了用外最大的幾個屬性。
生產者整體指標
生產者整體指標的屬性描述了生產者各個方面的信息,從消息批次的大小到內存緩沖區的使用情況。雖然這些指標在調試時都有一定用處,但只有少數幾個會經常用到,而在這幾.個指標當中,也只有一部分需要監控和告警。下面將討論一些平均數指標(以-avg結尾),它們都有相應的最大值(以-max結尾),不過這些最大值的用處很有限。
-
record-error-rate是一個很有必要對其設置告警的屬性。這個屬性的值一般情況下都是零,如果大于零,則說明生產者正在丟棄無法發送的消息。生產者配置了重試次數和回退策略,如果重試次數達到了上限,那么消息就會被丟棄。也可以跟蹤另外一個屬性record-retry-rate,不過這個屬性不如record-error-rate重要,因為重試是很正常的行為。
-
也可以對request-latency-avg屬性設置告警。這個屬性是指生產者向broker發送請求時平均花費的時間。應該為這個指標設置一個基線,并設定告警閾值。請求延遲的增加說明生產者請求速率變慢,有可能是網絡出了問題,也有可能是broker出了問題。不管是哪一種原因導致的,都是性能問題,并將導致生產者應用程序出現回壓和其他問題。
-
除了這些關鍵指標,還需要知道生產者發送了多大的消息量。有3個屬性為我們提供了3個不同的視圖:outgoing-byte-rate表示每秒發送的消息字節數,record-send-rate表示每秒發送的消息數量,request-rate表示每秒生產者發送給broker的請求數。一個請求可以包含一個或多個批次,一個批次可以包含一條或多條消息,一條消息由多個字節組成。把這些指標都顯示在儀表盤上會很有用。
-
有一些指標描述了消息、請求和批次的大小(都以字節為單位)。request-size-avg表示生嚴者發送給broker的請求的平均大小。batch-size-avg表示單個消息批次的平均大小(根據定義,批次包含了屬于同一個分區的多條消息)。record-size-avg表示單條消息的平均大小。對單個主題生產者來說,這些屬性提供了有關消息發送的有用信息。對多主題生產者(如MirrorMaker)來說,這些屬性就沒有那么有用了。除了這3個指標,還有另外一個指標records-per-request-avg,它表示單個生產請求包含的平均消息條數。
-
最后一個值得推薦的生產指標是record-queue-time-avg,它表示消息在發送給Kafka之前任生產者客戶端的平均等待時間(以毫秒為單位)。應用程序在使用生產者客戶端發送消息(調用send方法)之后,生產者會等待以下任一情況發生。
- 有足夠多的消息填滿批次(根據配置的batch,size)。
- 距離上一批次發送已經有足夠長的時間(根據配置的linger,ms)。
這兩種情況都會促使生產者客戶端關閉當前批次,并把它發送給broker。對于較為繁忙的一般會發生第二種情況。record-ueue-time-avg指標會告訴我們發送消息用了多長時間,因此,如果希望通過配置上面的兩個參數來降低應用程序延遲,那么這個指標會很有用。
個體broker指標和個體主題指標
除了生產者整體指標,還有一些MBean為每個broker連接和每個主題提供了一系列屬性。這些指標在調試問題時很有用,但在平常不需要對它們進行常規的監控。這些MBean屬性的名字與整體指標的名字一樣,表示的含義也一樣(只是它們是應用在個體broker或個體主題上)。
request-latency-avg是最為有用的個體broker指標,因為它比較穩定(在消息批次比較穩定的情況下),而且能夠顯示與某個broker之間的連接是否有問題。其他屬性,比如outgoing-byte-rate和request-latency-avg,它們會因為broker所包含分區的不同而有所不同。也就是說,這些指標會隨時間發生變化,完全取決于集群的狀態。
個體主題指標比個體broker指標要有趣一些,但它們只有在生產者向多個主題生成消息時才有用。當然,也只有在生產者不會向過多主題生成消息的情況下才有必要對這些指標進行常規的監控。例如,MirrorMaker有可能向成百上千個主題生成消息。我們無法逐個檢查這些指標,也幾乎不可能為它們設置合理的告警閾值。與個體broker指標一樣,個體主題指標一般用于診斷問題。例如,可以根據record-send-rate和 record-error-rate這兩個屬性將丟棄的消息隔離到特定的主題上(或者作為跨所有主題的可用消息)。另外還有一個指標byte-rate,它表示主題整體的消息速率(以字節/秒表示)。
2.7.2 消費者指標
與生產者客戶端類似,消費者客戶端將大量的指標屬性整合到少數的幾個MBean里,去掉了延遲百分位和速率移動平均數指標。因為消費者讀取消息的邏輯比生產者發送消息的邏輯復雜,所以消費者的指標會更多。
名稱 | JMX MBean |
---|---|
消費者整體 | kafka.consumer:type=consumer-metrics,client-id=CLIENTID |
獲取請求管理器 | kafka.consumer:type=consumer-fetch-manager-metrics,client-id=CLIENTID |
個體主題 | kafka.consumer:type=consumer-fetch-manager-metrics,client-id=CLIENTID,topic=TOPICNAME |
個體 broker | kafka.consumer:type=consumer-node-metrics,client-id=CLIENTID,node-id=node-BROKERID |
協調器 | kafka.consumer:type=consumer-coordinator-metrics,client-id=CLIENTID |
獲取請求管理器指標
在消費者客戶端,消費者整體指標MBean的作用并不是很大,因為有用的指標都在獲取請求管理器MBean里。消費者整體指標MBean包含了與底層網絡相關的指標,而獲取請求管理器MBean則包含了與字節、請求和消息速率相關的指標。與生產者客戶端不同,我們可以查看消費者客戶端提供的指標,但對它們設置告警并沒有太大意義。
對于獲取請求管理器,需要監控并設置告警的一個指標是fetch-latency-avg。與生產者客戶端的request-ldtency-avg類似,這個指標表示消費者向broker發送請求所需要的時間。為這個指標設直告警的問題在于,請求延遲是通過消費者fetch.min.bytes和fetch.max.wait.ms這兩個參數來控制的。一個低吞吐量的主題會出現不穩定的延遲,有時候broker的響應很快(有可用消息),有時候卻無法在fetch.max.wait.ms指定的時間內完成響應(沒有可用消息)。只有當主題有相對穩定和足夠的消息流量時,這個指標才更有用。
要想知道消費者客戶端正在處理多少消息流量,可以查看bytes-consumed-rate或 records-consumed-rate這兩個指標,最好是兩個都查看。它們分別表示客戶端每秒讀取的消息字節數和每秒讀取的消息條數。有些用戶為它們設置了最小值告警閾值,當消費者工作負載不足時,他們就會收到告警。不過需要注意的是,Kafka會試圖解開消費者客戶端和生產者客戶端之間的耦合,但消費者讀取消息的速率經常會依賴于生產者是否在正常運行,所以監控消費者的這些指標實際上是對生產者做了某些假設,這樣可能會導致誤報。
獲取請求管理器也提供了一些指標,有助于我們理解字節、消息和請求之間的關系。
fetch-rate表示消費者每秒發出的請求數量,fetch-size-avg表示這些請求的平均大小
(字節),records-per-request-avg表示每個請求的平均消息條數。需要注意的是,消費者并沒有提供與生產者record-size-avg相對應的指標,所以我們無法知道消息的平均大小。如果這個對你來說很重要,那么可以用其他指標來推算,或者在應用程序接收到消息之后獲取消息的大小。
個體broker指標和個體主題指標
與生產者客戶端類似,消費者客戶端也為每個broker連接和主題提供了很多指標,我們可以用它們診斷問題,但可能不需要進行常規的監控。與獲取請求管理器一樣,個體brokerJ request-latency-avg指標的用處也是有限的,具體取決于主題的消息流量。incoming-yte-rate和 request-rate分別表示從個體broker每秒讀取的消息字節數和每秒請求數。我們可以用它們診斷消費者與broker之間的連接問題。
如果讀取的是多個主題,那么消費者客戶端提供的個體主題指標就會很有用,否則它
們就與獲取請求管理器的指標一樣,我們也就沒有必要去收集它們。如果客戶端(如
OrMaker)讀取了大量主題,那么查看這些指標就會變得很困難。如果你真的打算收集“蘭指標,那么可以考慮收集最重要的3個:bytes-consumed-rate、records-consumed-rate和和fetch-size-avg。bytes-consumed-rate表示從某個主題每秒讀取的消息字節數,records-consumed-rate表示每秒讀取的消息條數,fetch-size-avg表示每個請求的平均大小。
消費者協調器指標
多個消費者客戶端組成了消費者群組,群組中會發生一些需要協調的活動,比如新成員加入,或者通過向broker發送心跳來維持群組的成員關系。消費者協調器負責處理這些協調工作,并提供了一組指標。與其他指標一樣,協調器指標也提供了很多
數字,但只有一小部分需要進行常規的監控。
消費者群組在執行同步操作時可能會導致消費者出現停頓。此時,群組中的消費者正在協商哪些分區應該由哪些消費者讀取。停頓的時間長短取決于分區的數量。協調器提供了sync-time-avg指標,表示同步活動發生的平均時長(以毫秒為單位)。sync-rate屬性也很有用,表示消費者群組每秒發生同步的次數。在一個穩定的消費者群組中,這個數字大多數時候是零。
Kafka會將消費者提交的偏移量作為讀取進度的檢查點。消費者既可以基于固定的時間間隔自動提交偏移量,也可以在代碼中手動提交偏移量。提交偏移量也是一種生成消息的請求(它們有自己的請求類型),提交的偏移量會作為消息被發送到一個特定的主題上。協調器提供的commit-latency-avg屬性表示提交偏移量所需的平均時長。我們也需要監控這個指標,就像監控生產者請求延遲一樣。還要為它設定一個預期的基線和合理的告警閾值。
協調器指標的最后一個屬性是assigned-partitions,表示分配給消費者客戶端(群組中的單個消費者)的分區數量。這個屬性之所以有用,是因為我們可以通過比較整個群組各個消費者分配到的分區數量來判斷群組的負載是否均衡。可以使用這個屬性來識別因協調器分區分配算法所導致的負載不均衡問題。
2.7.3 配額
Kafka可以對客戶端請求進行節流,防止某個客戶端拖垮整個集群。對消費者客戶端和生產者客戶端來說,這都是可配的,并用每秒允許單個客戶端從單個broker讀取多少字節或寫入多少字節來表示。它有一個broker級別的默認值,客戶端可以動態覆蓋。當broker發現客戶端的流量已經超出配額時,它會暫緩向客戶端返回響應,直到客戶端流量降到配額以下。
broker并不會將客戶端被節流的錯誤碼放在響應消息里。也就是說,對應用程序來說如果不監控這些指標,就不會知道發生了節流。
名稱 | JMX MBean |
---|---|
消費者 | kafka.consumer:type=consumer-fetch-manager-metrics,client-id=CLIENTID的屬性fetch-throttle-time-avg |
生產者 | kafka.producer:type=producer-metrics,client-id=CLIENTID的屬性 produce-throttle-time-avg |
在默認情況下,broker不會開啟配額限制。但不管有沒有開啟,監控這些指標總是安全無害的。況且,配額限制有可能在未來某個時刻被啟用,從一開始就監控這些指標要比在后期添加更容易。
2.8 滯后監控
對消費者來說,取需要被監控的指標是滯后消息數量,也就是分區生成的最后一條消息和費者讀取的敢后一條消息之間的差值。前面講過,對于消費者滯后,使用外部監控工具使用客戶端提供的指標要好得多。雖然消費者提供了滯后指標,但該指標存在一個問題,即它只表示單個分區(也就是具有最大滯后的那個分區)的滯后,所以不能準確地告長我們消費者的整體滯后情況。另外,它需要消費者做一些額外的操作,因為這個指標是由消費者對每個發出的獲取請求進行計算得出的。如果消費者發生崩潰或離線,那么這個指標要么不準確,要么不可用。
監控消費者滯后最好的辦法是使用外部工具,它們既能觀察broker的分區狀態(通過跟蹤最近生成的消息的偏移量),也能觀察消費者的狀態(通過跟蹤消費者群組提交的最新偏移量)。這種監控方式提供了一種不依賴消費者狀態的客觀視圖。我們需要監控消費組讀取的每一個分區。對于大型的消費者,比如MirrorMaker,這意味著需要監控成千上萬個分區。
使用命令行工具獲取消費者群組的信息,包括提交的偏移量和滯后的消息數量。如果直接監控由命令行工具提供的信息,那么也存在一些問題。首先,需要為每個分區定義一個合理的滯后閾值。每小時接收100條消息的主題和每秒接收10萬條消息的主題的滯后閾值顯然不同。其次,需要將滯后指標導入監控系統,并為它們設置告警。如果一個消費者群組讀取了1500個主題,這些主題的分區數量超過了10萬個,那么
這將是一項令人望而生畏的任務。
可以使用Burrow 來降低這項任務的復雜性。Burrow是一個開源的應用程序,最初由
LinkedIn開發。它會收集集群消費者群組的滯后信息,并為每個群組計算出一個獨立的狀態,告訴我們群組是否運行正常、是否出現了滯后、速度是否變慢或者是否已經停止工作。它不需要通過監控消費者群組的處理進度來獲得閾值,不過我們仍然可以從中獲得滯后的消息絕對數量。LinkedIn工程博客“Burrow:Kafka Consumer Monitoring Reinvented”介紹了Burrow的工作原理。Burrow既可用于監控一個集群中的消費者,也可用于監控多個集群,而且可以很容易被集成到已有的監控和告警系統中。
如果沒有其他選擇,則可以考慮查看消費者客戶端的records-lag-max指標,它提供了消費者消費狀態的部分視圖。不管怎樣,仍然建議使用像Burrow這樣的外部監控系統。
2.9 端到端監控
我們推薦的另一種外部監控解決方案是端到端監控,它為Kafka集群的健康狀態提供了一種客戶端視圖。消費者客戶端和生產者客戶端的一些指標能夠說明集群可能出現了問題,但這里有猜想的成分,因為延遲的增加有可能是由客戶端、網絡或Kafka本身引起的。另外,你原本的任務可能只是管理Kafka集群,但現在也需要監控客戶端。
你需要知道下面這兩個問題的答案:
- 可以向Kafka集群寫入消息嗎?
- 可以從Kafka集群讀取消息嗎?
理想情況下,你可能希望對每一個主題都執行這些操作。但是,在大多數情況下,向每一個主題都注入人為制造的流量是不合理的。所以,可以考慮將問題提升到broker級別,而這正是Xinfra Monitor(之前叫作Kafka Monitor)要做的事情。這個工具最初由LinkedIn的Kafka團隊開發并開源。它會持續地向一個橫跨集群所有broker的主題生成消息,并讀取這些消息。然后會監控每個broker生產請求和讀取請求的可用性,以及生產消息和讀取消息之間的整體延遲。這種從外部驗證Kafka集群運行狀態的監控方式是非常有價值的,因為與監控消費者滯后一樣,broker本身無法告知客戶端集群是否運行正常。
附錄
1 JMX
1.1 什么是JMX
JMX,全稱 Java Management Extensions,是在 J2SE 5.0 版本中引入的一個功能。提供了一種在運行時動態管理資源的框架,主要用于企業應用程序中實現可配置或動態獲取應用程序的狀態。JMX 提供了一種簡單、標準的監控和管理資源的方式,對于如何定義一個資源給出了明確的模式。
1.2 JMX的架構
Oracle官方網站關于JMX的架構描述
資源探測(Instrumentation)
資源探測的核心是用于資源管理的 Managed bean,簡稱 MBean。MBean 表示在 Java 虛擬機中運行的資源,例如應用程序或 Java EE 技術服務(事務監視器、JDBC 驅動程序等)。MBean 可用來收集重點關注的統計信息,比如性能、資源使用以及問題等,也可以用于獲取和設置應用程序配置或屬性(推/拉模式),也還可以用于故障通知或者狀態變更(推送)等。
代理(Agent)
代理充當管理資源和應用程序之間的中介。代理層提供對來自管理應用程序的管理資源的訪問。JMX 代理可以在嵌入在管理資源的機器中的 JVM 中運行,也可以位于遠程位置。代理不需要知道它公開的資源以及使用公開 MBean 的管理器應用程序。它充當處理 MBean 的服務,并允許通過通過 Connector 或 Adaptor 公開的協議來操作 MBean。
代理層的職責之一是將應用程序與管理資源分離。應用程序不會直接引用管理的資源,而是通過 JMX 代理的對象名稱引用調用管理操作。代理層的核心組件是 MBean Server,作為 MBean 的注冊中心,并允許應用程序發現已注冊 MBean 的管理接口。除此之外,代理層提供了四種代理服務,使管理 MBean 更加容易:計時器服務、監控服務、關系服務以及動態 MBean 加載服務。
想要 MBean Server 可以管理 MBean 資源,首先要把資源注冊到 MBean Server 上,任何符合 JMX 的 MBean 資源都可以進行注冊。
遠程管理(Remote Management)
遠程管理是 JMX 架構的最外層,該層負責使 JMX 代理對外部世界可用。代理層并沒有實現遠程訪問方法,所以在遠程管理層會提供一個遠程通信接口對外提供服務。提供對外服務需要通過使用一個或多個 JMX Connector 或者 Adaptor 來實現。Connector 和 Adaptor 允許應用程序通過特定協議訪問遠程 JMX 代理,這樣來自不同 JVM 的應用程序就可以調用 MBean Server 上的管理操作、獲取或設置管理屬性、實例化和注冊新的 MBean,以及注冊和接收來自管理資源的通知。
Connector 是將代理 API 暴露給其他分布式技術,例如 Java RMI,而 Adaptor 則是通過 HTTP 或者 SNMP 等不同的協議提供對 MBean 的可見性。事實上,一個代理可以使用許多不同的技術。Connector 和 Adaptor 在 JMX 環境中提供相同的功能。
1.2 示例代碼
https://gitee.com/qp1886358/jmx