gc日志怎么看_你应该怎么监控Kafka?
監控 Kafka,歷來都是個老大難的問題。無論是在我維護的微信公眾號,還是 Kafka QQ群里面,大家問得最多的問題,一定是 Kafka 的監控。大家提問的內容看似五花八門,但真正想了解的,其實都是監控這點事,也就是我應該監控什么,怎么監控。
我個人認為,和頭疼醫頭、腳疼醫腳的問題類似,在監控 Kafka 時,如果我們只監控Broker 的話,就難免以偏概全。單個 Broker 啟動的進程雖然屬于 Kafka 應用,但它也是一個普通的 Java 進程,更是一個操作系統進程。因此,我覺得有必要從 Kafka 主機、JVM和 Kafka 集群本身這三個維度進行監控。
主機監控
主機級別的監控,往往是揭示線上問題的第一步。所謂主機監控,指的是監控 Kafka 集群Broker 所在的節點機器的性能。通常來說,一臺主機上運行著各種各樣的應用進程,這些進程共同使用主機上的所有硬件資源,比如 CPU、內存或磁盤等。
常見的主機監控指標包括但不限于以下幾種:
- 機器負載(Load)
- CPU 使用率
- 內存使用率,包括空閑內存(Free Memory)和已使用內存(Used Memory)
- 磁盤 I/O 使用率,包括讀使用率和寫使用率
- 網絡 I/O 使用率
- TCP 連接數
- 打開文件數
- inode 使用情況
考慮到我們并不是要系統地學習調優與監控主機性能,因此我并不打算對上面的每一個指標都進行詳細解釋,我重點分享一下機器負載和 CPU 使用率的監控方法。我會以 Linux 平臺為例來進行說明,其他平臺應該也是類似的。
首先,我們來看一張圖片。我在 Kafka 集群的某臺 Broker 所在的主機上運行 top 命令,輸出的內容如下圖所示:
在圖片的右上角,我們可以看到 load average 的 3 個值:4.85,2.76 和 1.26,它們分別代表過去 1 分鐘、過去 5 分鐘和過去 15 分鐘的 Load 平均值。在這個例子中,我的主機總共有 4 個 CPU 核,但 Load 值卻達到了 4.85,這就說明,一定有進程暫時“搶不到”任何 CPU 資源。同時,Load 值一直在增加,也說明這臺主機上的負載越來越大。
舉這個例子,其實我真正想說的是 CPU 使用率。很多人把 top 命令中“%CPU”列的輸出值當作 CPU 使用率。比如,在上面這張圖中,PID 為 2637 的 Java 進程是 Broker 進程,它對應的“%CPU”的值是 102.3。你不要認為這是 CPU 的真實使用率,這列值的真實含義是進程使用的所有 CPU 的平均使用率,只是 top 命令在顯示的時候轉換成了單個CPU。因此,如果是在多核的主機上,這個值就可能會超過 100。在這個例子中,我的主機有 4 個 CPU 核,總 CPU 使用率是 102.3,那么,平均每個 CPU 的使用率大致是25%。
JVM監控
除了主機監控之外,另一個重要的監控維度就是 JVM 監控。Kafka Broker 進程是一個普通的 Java 進程,所有關于 JVM 的監控手段在這里都是適用的。
監控 JVM 進程主要是為了讓你全面地了解你的應用程序(Know Your Application)。具體到 Kafka 而言,就是全面了解 Broker 進程。比如,Broker 進程的堆大小(HeapSize)是多少、各自的新生代和老年代是多大?用的是什么 GC 回收器?這些監控指標和配置參數林林總總,通常你都不必全部重點關注,但你至少要搞清楚 Broker 端 JVM 進程的Minor GC 和 Full GC 的發生頻率和時長、活躍對象的總大小和 JVM 上應用線程的大致總數,因為這些數據都是你日后調優 Kafka Broker 的重要依據。
我舉個簡單的例子。假設一臺主機上運行的 Broker 進程在經歷了一次 Full GC 之后,堆上存活的活躍對象大小是 700MB,那么在實際場景中,你幾乎可以安全地將老年代堆大小設置成該數值的 1.5 倍或 2 倍,即大約 1.4GB。不要小看 700MB 這個數字,它是我們設定Broker 堆大小的重要依據!
很多人會有這樣的疑問:我應該怎么設置 Broker 端的堆大小呢?其實,這就是最合理的評估方法。試想一下,如果你的 Broker 在 Full GC 之后存活了 700MB 的數據,而你設置了堆大小為 16GB,這樣合理嗎?對一個 16GB 大的堆執行一次 GC 要花多長時間啊?!因此,我們來總結一下。要做到 JVM 進程監控,有 3 個指標需要你時刻關注:
總之,你對 Broker 進程了解得越透徹,你所做的 JVM 調優就越有效果。
談到具體的監控,前兩個都可以通過 GC 日志來查看。比如,下面的這段 GC 日志就說明了 GC 后堆上的存活對象大小。
2020-07-06T09:13:03.809+0800: 552.982: [GC cleanup 827M->645M(1024M), 0.0019078 secs]這個 Broker JVM 進程默認使用了 G1 的 GC 算法,當 cleanup 步驟結束后,堆上活躍對象大小從 827MB 縮減成 645MB。另外,你可以根據前面的時間戳來計算每次 GC 的間隔和頻率。
自 0.9.0.0 版本起,社區將默認的 GC 收集器設置為 G1,而 G1 中的 Full GC 是由單線程執行的,速度非常慢。因此,你一定要監控你的 Broker GC 日志,即以 kafkaServer-gc.log 開頭的文件。注意不要出現 Full GC 的字樣。一旦你發現 Broker 進程頻繁 FullGC,可以開啟 G1 的 -XX:+PrintAdaptiveSizePolicy 開關,讓 JVM 告訴你到底是誰引發了 Full GC。
集群監控
說完了主機和 JVM 監控,現在我來給出監控 Kafka 集群的幾個方法。
1. 查看 Broker 進程是否啟動,端口是否建立。
千萬不要小看這一點。在很多容器化的 Kafka 環境中,比如使用 Docker 啟動 KafkaBroker 時,容器雖然成功啟動了,但是里面的網絡設置如果配置有誤,就可能會出現進程已經啟動但端口未成功建立監聽的情形。因此,你一定要同時檢查這兩點,確保服務正常運行。
2. 查看 Broker 端關鍵日志。
這里的關鍵日志,主要涉及 Broker 端服務器日志 server.log,控制器日志 controller.log以及主題分區狀態變更日志 state-change.log。其中,server.log 是最重要的,你最好時刻對它保持關注。很多 Broker 端的嚴重錯誤都會在這個文件中被展示出來。因此,如果你的 Kafka 集群出現了故障,你要第一時間去查看對應的 server.log,尋找和定位故障原因。
3. 查看 Broker 端關鍵線程的運行狀態。
這些關鍵線程的意外掛掉,往往無聲無息,但是卻影響巨大。比方說,Broker 后臺有個專屬的線程執行 Log Compaction 操作,由于源代碼的 Bug,這個線程有時會無緣無故地“死掉”,社區中很多 Jira 都曾報出過這個問題。當這個線程掛掉之后,作為用戶的你不會得到任何通知,Kafka 集群依然會正常運轉,只是所有的 Compaction 操作都不能繼續了,這會導致 Kafka 內部的位移主題所占用的磁盤空間越來越大。因此,我們有必要對這些關鍵線程的狀態進行監控。
可是,一個 Kafka Broker 進程會啟動十幾個甚至是幾十個線程,我們不可能對每個線程都做到實時監控。所以,我跟你分享一下我認為最重要的兩類線程。在實際生產環境中,監控這兩類線程的運行情況是非常有必要的。
Log Compaction 線程,這類線程是以 kafka-log-cleaner-thread 開頭的。就像前面提到的,此線程是做日志 Compaction 的。一旦它掛掉了,所有 Compaction 操作都會中斷,但用戶對此通常是無感知的。
副本拉取消息的線程,通常以 ReplicaFetcherThread 開頭。這類線程執行 Follower 副本向 Leader 副本拉取消息的邏輯。如果它們掛掉了,系統會表現為對應的 Follower 副本不再從 Leader 副本拉取消息,因而 Follower 副本的 Lag 會越來越大。
不論你是使用 jstack 命令,還是其他的監控框架,我建議你時刻關注 Broker 進程中這兩類線程的運行狀態。一旦發現它們狀態有變,就立即查看對應的 Kafka 日志,定位原因,因為這通常都預示會發生較為嚴重的錯誤。
4. 查看 Broker 端的關鍵 JMX 指標。
Kafka 提供了超多的 JMX 指標供用戶實時監測,我來介紹幾個比較重要的 Broker 端 JMX指標:
- BytesIn/BytesOut:即 Broker 端每秒入站和出站字節數。你要確保這組值不要接近你的網絡帶寬,否則這通常都表示網卡已被“打滿”,很容易出現網絡丟包的情形。
- NetworkProcessorAvgIdlePercent:即網絡線程池線程平均的空閑比例。通常來說,你應該確保這個 JMX 值長期大于 30%。如果小于這個值,就表明你的網絡線程池非常繁忙,你需要通過增加網絡線程數或將負載轉移給其他服務器的方式,來給該 Broker 減負。
- RequestHandlerAvgIdlePercent:即 I/O 線程池線程平均的空閑比例。同樣地,如果該值長期小于 30%,你需要調整 I/O 線程池的數量,或者減少 Broker 端的負載。
- UnderReplicatedPartitions:即未充分備份的分區數。所謂未充分備份,是指并非所有的 Follower 副本都和 Leader 副本保持同步。一旦出現了這種情況,通常都表明該分區有可能會出現數據丟失。因此,這是一個非常重要的 JMX 指標。
- ISRShrink/ISRExpand:即 ISR 收縮和擴容的頻次指標。如果你的環境中出現 ISR 中副本頻繁進出的情形,那么這組值一定是很高的。這時,你要診斷下副本頻繁進出 ISR 的原因,并采取適當的措施。
- ActiveControllerCount:即當前處于激活狀態的控制器的數量。正常情況下,Controller 所在 Broker 上的這個 JMX 指標值應該是 1,其他 Broker 上的這個值是 0。如果你發現存在多臺 Broker 上該值都是 1 的情況,一定要趕快處理,處理方式主要是查看網絡連通性。這種情況通常表明集群出現了腦裂。腦裂問題是非常嚴重的分布式故障,Kafka 目前依托 ZooKeeper 來防止腦裂。但一旦出現腦裂,Kafka 是無法保證正常工作的。
其實,Broker 端還有很多很多 JMX 指標,除了上面這些重要指標,你還可以根據自己業務的需要,去官網查看其他 JMX 指標,把它們集成進你的監控框架。
5. 監控 Kafka 客戶端。
客戶端程序的性能同樣需要我們密切關注。不管是生產者還是消費者,我們首先要關心的是客戶端所在的機器與 Kafka Broker 機器之間的網絡往返時延(Round-Trip Time,RTT)。通俗點說,就是你要在客戶端機器上 ping 一下 Broker 主機 IP,看看 RTT 是多少。
我曾經服務過一個客戶,他的 Kafka 生產者 TPS 特別低。我登到機器上一看,發現 RTT 是1 秒。在這種情況下,無論你怎么調優 Kafka 參數,效果都不會太明顯,降低網絡時延反而是最直接有效的辦法。
除了 RTT,客戶端程序也有非常關鍵的線程需要你時刻關注。對于生產者而言,有一個以kafka-producer-network-thread 開頭的線程是你要實時監控的。它是負責實際消息發送的線程。一旦它掛掉了,Producer 將無法正常工作,但你的 Producer 進程不會自動掛掉,因此你有可能感知不到。對于消費者而言,心跳線程事關 Rebalance,也是必須要監控的一個線程。它的名字以 kafka-coordinator-heartbeat-thread 開頭。
除此之外,客戶端有一些很重要的 JMX 指標,可以實時告訴你它們的運行情況。
從 Producer 角度,你需要關注的 JMX 指標是 request-latency,即消息生產請求的延時。這個 JMX 最直接地表征了 Producer 程序的 TPS;而從 Consumer 角度來說,records-lag 和 records-lead 是兩個重要的 JMX 指標。總之,它們直接反映了 Consumer 的消費進度。如果你使用了 Consumer Group,那么有兩個額外的 JMX 指標需要你關注下,一個是 joinrate,另一個是 sync rate。它們說明了 Rebalance 的頻繁程度。如果在你的環境中,它們的值很高,那么你就需要思考下 Rebalance 頻繁發生的原因了。
總結
好了,我們來小結一下。本文介紹了監控 Kafka 的方方面面。除了監控 Kafka 集群,還推薦你從主機和 JVM 的維度進行監控。對主機的監控,往往是我們定位和發現問題的第一步。JVM 監控同樣重要。要知道,很多 Java 進程碰到的性能問題是無法通過調整Kafka 參數是解決的。最后,羅列了一些比較重要的 Kafka JMX 指標。
推薦閱讀
絕對干貨,掌握這27個知識點,輕松拿下80%的技術面試(Java崗)
一線大廠為什么面試必問分布式?
在一次又一次的失敗中,我總結了這份萬字的《MySQL性能調優筆記》
并發編程詳解:十三個工具類,十大設計模式,從理論基礎到案例實戰
如何高效部署分布式消息隊列?這份《RabbitMQ實戰》絕對可以幫到你
總結
以上是生活随笔為你收集整理的gc日志怎么看_你应该怎么监控Kafka?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: openlayers集成echarts实
- 下一篇: 网络知识:秒懂你家的网络连接方式