解决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 中堆积的数据量达到数亿条。
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 即可。
posted on 2022-02-24 21:52 luzhouxiaoshuai 阅读(3079) 评论(0) 编辑 收藏 举报