轉載自博客:
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 中堆積的數據量達到數億條。
kafka 消息生產消費監控
問題分析:
經過電話溝通后,拿到了客戶的 logstash 配置如下:
logstash.conf
-
input{
-
kafka{
-
bootstrap_servers => "xx.xx.xx.xx:9092"
-
#topics => [ "xx-yhtplus","xx-order","xx-user","xx-image","xx-goods","xx-activities","xx-wechat"]
-
topics_pattern => "xx-.*"
-
consumer_threads => 24
-
decorate_events => true
-
group_id => "logstash"
-
codec => "json"
-
auto_offset_reset => "latest"
-
}
-
}
-
filter {
-
mutate {
-
convert => [ "respones-time", "float"]
-
}
-
}
-
output {
-
elasticsearch {
-
hosts => [ "http://騰訊雲VIP:9200"]
-
user => ""
-
password => ""
-
index => "%{[@metadata][topic]}-%{+YYYY-MM-dd}"
-
}
-
}
logstash.yml
-
pipeline.workers: 8
-
pipeline.output.workers: 8
-
pipeline.batch.size: 5000
-
pipeline.batch.delay: 10
經過了解發現,客戶在騰訊雲 tke 中啟動了 8 個 logstash 進程,但是實際上只有 3 個是活躍的,另外 5 個一直處於空閑狀態,且每個 logstash 進程只使用了不到 3 核的 CPU。
logstash 進程
客戶反饋對 logstash.yml 配置文件做了多次調整,均不生效。
pipeline.workers 設置為 logstash 核數;
pipeline.batch.size 從 5000 到 20000 均有調整。
通過客戶的配置優化反饋來看,問題應該不是出在 logstash.yml 配置的調整上,而極有可能出現在消費 kafka 的源頭上。我們可以把 logstash 理解為一個水管,從kafka 上游取水,往下游 ES 中灌。既然上游的水有積壓,那無非就是調大進水口或者調大出水口。既然 ES 還沒到瓶頸,且 logstash.yml 相關配置無論怎么優化調整,依然沒有更多的水灌到 ES 中來。那可以肯定的是問題不在出水口,而是在kafka 這側的進水口出了點問題,即消費 kafka 的口子沒有完全打開。
三、優化建議
經過和客戶更細致的溝通,得到如下反饋:
-
logstash 是統一消費一個消費組,該消費組中一共有 24 個 topic;
-
24 個 topic 中有 2 個 topic 數據量非常大,其他 22 個 topic 數據量一般;
-
每個 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 的分區數。
起三組 logstash 消費進程
做完這些調整后,再次觀察 kafka 的消費情況,已經從原來的 180w/min 提升到了520w/min。消費性能立馬提升了近 3 倍。客戶表示非常滿意。再也不用擔心兩天后促銷活動的消息堆積問題。
優化后的消費能力
四、問題解答
1、這個客戶為什么用冷熱分離的架構呢?
答:因為該客戶對數據的保存時間有嚴格要求,即數據至少要保存兩個月的時間,但是對 ES 的熱節點 ssd 架構比較敏感,因此我們推薦了客戶使用騰訊雲 ES 的冷熱分離的架構,即新索引在熱節點上創建,數據保存一周后,通過 ES 提供的索引生命周期管理,自動將熱節點上的數據遷移到冷節點中,冷節點使用騰訊雲高性能雲盤,價格相對 ssd 更加便宜。數據滿 2 個月后,通過 ES 的索引生命周期自動將冷節點上的數據進行刪除,以釋放更多的存儲空間。
2、明明設置了索引生命周期管理,但是熱節點上的數據都超過一周了為什么還是沒有遷移到冷節點?
答:索引的生命周期配置只會對新增的索引生效,默認對存量的索引是不生效的,這是為了防止對存量比較重要的索引造成誤刪除等不可逆的影響,如果需要對存量索引也生效的話,可以通過設置存量索引的 settings,關聯對應的 Policy 即可。