解決kafka 消息堆積問題的排查及調優


轉載自博客:

https://blog.csdn.net/u012811805/article/details/121347269

一、背景說明

深夜接到客戶緊急電話,反饋騰訊雲 kafka 中有大量消息堆積未及時消費。每分鍾堆積近 100w 條數據。但是查看 ES 監控,各項指標都遠還沒到性能瓶頸。后天公司就要搞電商促銷活動,到時候數據量是現在的至少 2 倍,這讓客戶很是着急。這究竟是怎么回事呢?該從何排查才能發現問題所在呢?下面我們一起還原“案發”現場。

二、客戶面臨問題及分析

集群使用場景:使用騰訊雲 ES 集群存儲業務日志數據。

集群架構:冷熱架構。

集群規模:3個熱節點:8C32G+4T SSD ;4個溫節點:8C32G+5T高性能雲盤。

數據鏈路:Filebeat 采集日志數據 ---> 騰訊雲 kafka ----> 客戶自建 logstash ----> 騰訊雲 Elasticsearch

具體問題反饋:

kafka 的日常消息生產量在 260w/min。但是看 kafka 監控發現消費量只有180w/min。也就是說每分鍾會堆積近 100w 條消息,積累了一段時間后,kafka 中堆積的數據量達到數億條。

f31b9b79b4a7a1ec33d26849f9b4a571.png

kafka 消息生產消費監控

問題分析:

經過電話溝通后,拿到了客戶的 logstash 配置如下:

logstash.conf

  1.  
    input{
  2.  
    kafka{
  3.  
    bootstrap_servers => "xx.xx.xx.xx:9092"
  4.  
    #topics => [ "xx-yhtplus","xx-order","xx-user","xx-image","xx-goods","xx-activities","xx-wechat"]
  5.  
    topics_pattern => "xx-.*"
  6.  
    consumer_threads => 24
  7.  
    decorate_events => true
  8.  
    group_id => "logstash"
  9.  
    codec => "json"
  10.  
    auto_offset_reset => "latest"
  11.  
    }
  12.  
    }
  13.  
    filter {
  14.  
    mutate {
  15.  
    convert => [ "respones-time", "float"]
  16.  
    }
  17.  
    }
  18.  
    output {
  19.  
    elasticsearch {
  20.  
    hosts => [ "http://騰訊雲VIP:9200"]
  21.  
    user => ""
  22.  
    password => ""
  23.  
    index => "%{[@metadata][topic]}-%{+YYYY-MM-dd}"
  24.  
    }
  25.  
    }

logstash.yml

  1.  
    pipeline.workers: 8
  2.  
    pipeline.output.workers: 8
  3.  
    pipeline.batch.size: 5000
  4.  
    pipeline.batch.delay: 10

經過了解發現,客戶在騰訊雲 tke 中啟動了 8 個 logstash 進程,但是實際上只有 3 個是活躍的,另外 5 個一直處於空閑狀態,且每個 logstash 進程只使用了不到 3 核的 CPU。

3fe12dde76f9ec9a49086c8f13bd806f.png

logstash 進程

客戶反饋對 logstash.yml 配置文件做了多次調整,均不生效。

pipeline.workers 設置為 logstash 核數;

pipeline.batch.size 從 5000 到 20000 均有調整。

通過客戶的配置優化反饋來看,問題應該不是出在 logstash.yml 配置的調整上,而極有可能出現在消費 kafka 的源頭上。我們可以把 logstash 理解為一個水管,從kafka 上游取水,往下游 ES 中灌。既然上游的水有積壓,那無非就是調大進水口或者調大出水口。既然 ES 還沒到瓶頸,且 logstash.yml 相關配置無論怎么優化調整,依然沒有更多的水灌到 ES 中來。那可以肯定的是問題不在出水口,而是在kafka 這側的進水口出了點問題,即消費 kafka 的口子沒有完全打開。

三、優化建議

經過和客戶更細致的溝通,得到如下反饋:

  1. logstash 是統一消費一個消費組,該消費組中一共有 24 個 topic;

  2. 24 個 topic 中有 2 個 topic 數據量非常大,其他 22 個 topic 數據量一般;

  3. 每個 topic 設置為 3 個 partition。

得到如上反饋后,針對該問題,我這邊給客戶更進一步的優化方案如下:

1. 將 topic 進行拆分,兩個大的 topic 分別單獨作為一個消費組,其他的 22 個 topic 作為一個消費組,這樣將一個消費組拆分出三個消費組進行消費;

2. 增大 topic 的 partition 數量,將兩個大的 topic 的 partition 調整為 24,其他的22 個 topic 的 partition 調整為 8;

3. 起三組 logstash,分別消費對應的消費組;

4. 將每組 logstash 中 consumer_threads 和每組消費組的總 partition 大小設置保持一致,即保證每個 logstash 的 consumer_thread 數目* logstash 的進程數目 = kafka 對應 topic 的分區數。

dd6e59c0ac38f55df1e1d9ae3cb77d81.png

起三組 logstash 消費進程

做完這些調整后,再次觀察 kafka 的消費情況,已經從原來的 180w/min 提升到了520w/min。消費性能立馬提升了近 3 倍。客戶表示非常滿意。再也不用擔心兩天后促銷活動的消息堆積問題。

6ff0ae82d33efe53e674ba03d5db453f.png

優化后的消費能力

四、問題解答

1、這個客戶為什么用冷熱分離的架構呢?

答:因為該客戶對數據的保存時間有嚴格要求,即數據至少要保存兩個月的時間,但是對 ES 的熱節點 ssd 架構比較敏感,因此我們推薦了客戶使用騰訊雲 ES 的冷熱分離的架構,即新索引在熱節點上創建,數據保存一周后,通過 ES 提供的索引生命周期管理,自動將熱節點上的數據遷移到冷節點中,冷節點使用騰訊雲高性能雲盤,價格相對 ssd 更加便宜。數據滿 2 個月后,通過 ES 的索引生命周期自動將冷節點上的數據進行刪除,以釋放更多的存儲空間。

2、明明設置了索引生命周期管理,但是熱節點上的數據都超過一周了為什么還是沒有遷移到冷節點?

答:索引的生命周期配置只會對新增的索引生效,默認對存量的索引是不生效的,這是為了防止對存量比較重要的索引造成誤刪除等不可逆的影響,如果需要對存量索引也生效的話,可以通過設置存量索引的 settings,關聯對應的 Policy 即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM