一.背景:

最近发现生产ELK集群中的Logstash服务器内存资源和CPU负载经常性跑高的情况,同时考虑到Logstash节点为单点部署没有容灾特性,需增加一个Logstash节点,并同时对Kafka做相关调优,调整每个topic的分区数partition和副本数replica,提升集群的吞吐能力和容灾能力。

二.系统环境:

所使用集群架构组件及版本信息如下:

操作系统OS版本:CentOS Linux release 7.9.2009 (Core) 

名称  

版本号

filebeat

7.10.0

kafka

2.4.1

zookeeper

3.5.7

logstash

7.5.2

elasticsearch

7.5.2

kibana

7.5.2

三.实施步骤:

以下涉及到的操作输入命令根据实际情况路径和文件名修改

1.Kafka调优:

(1)首先备份原有配置文件:

cp -a server.properties server.properties.bak

logstash消费kafka消息延迟 logstash 消费kafka消息堆积处理_kafka

(2)然后修改server.properties配置文件里的

logstash消费kafka消息延迟 logstash 消费kafka消息堆积处理_logstash消费kafka消息延迟_02

打开自动创建标题topic的选项(上图划红线处),否则后续出现新的项目的时候,生产者传递过来的数据不会自动创建对应的标题,自动指定该标题的分区partition和副本replica,配合后续参数项使用

(3)调整用于负责网络收发数据和处理数据读写请求的线程数,这两个参数需要根据实际的网络带宽情况和磁盘的io性能设置

logstash消费kafka消息延迟 logstash 消费kafka消息堆积处理_logstash_03

(4) 调整kafka中生成除内置标题topic之外标题的分区数partition,副本数replica,副本复制成功最小确认数min.insync.replica,副本复制成功反馈机制ack,标题offset的分区数,副本数,等参数项

logstash消费kafka消息延迟 logstash 消费kafka消息堆积处理_负载均衡_04

 (5)在调整标题topic的分区数num.partition后,需要让系统把数据分发和同步到新的分区中,形成副本集,所以这里要调整触发重新分发文件的时间为1个小时,以便尽快让数据均衡到每个新的节点,所以把log.retention.hours调整由24调整为1

logstash消费kafka消息延迟 logstash 消费kafka消息堆积处理_kafka_05

(6)以上修改配置文件的步骤在kafka集群所有节点上都执行一遍,确保集群内节点的配置一致

(7)Kafka的配置文件修改完毕后,先不要重启kafka,否则会出现当前运行集群的数据和配置文件不匹配的错误,所以需要首先手动调整原有的标题topic的分区数partition和副本数replica,首先list一下现有分区

/usr/local/elk/src/kafka-2.4.1/bin/kafka-topics.sh --list --zookeeper localhost:2181

 

logstash消费kafka消息延迟 logstash 消费kafka消息堆积处理_logstash消费kafka消息延迟_06

 其中除了__consumer_offsets为kafka内置标题topic不可进行在线调整其分区数外(副本数可以在线调整),其余均为用户创建的标题,可以通过kafka提供的脚本工具在线调整,见下文

(8)接着首先调整内置标题__consumer_offsets,由于其分区partition默认为50且不可调整,所以只能通过脚本工具bin/kafka-reassign-partitions.sh调整其副本数replica,首先根据步骤4中配置文件的定义,确定其副本数为3,然后可以编写json文件定义其副本配置如下:

logstash消费kafka消息延迟 logstash 消费kafka消息堆积处理_kafka_07

 共50个分区,所以需要有50个配置块,编辑完文件后保存为partition-topic-test3.json然后使用如下命令调整副本数

/usr/local/elk/src/kafka-2.4.1/bin/kafka-reassign-partitions.sh --reassignment-json-file /root/partitions-topic-test3.json --zookeeper localhost:2181 --execute

logstash消费kafka消息延迟 logstash 消费kafka消息堆积处理_kafka_08

之后使用下面命令确认副本调整情况,确认每一个分区状态都已调整成功才算调整完毕

/usr/local/elk/src/kafka-2.4.1/bin/kafka-reassign-partitions.sh --reassignment-json-file /root/partitions-topic-test3.json --zookeeper localhost:2181 --verify

logstash消费kafka消息延迟 logstash 消费kafka消息堆积处理_kafka_09

(9)处理完内置标题后,接着来处理其他标题,根据步骤(4)中配置文件的定义,普通标题topic的默认分区数为8,然后使用下图的脚本工具在线调整其分区数为8,如下

/usr/local/elk/src/kafka-2.4.1/bin/kafka-topics.sh --zookeeper localhost:2181 --alter --topic mms-admin-test --partitions 8

logstash消费kafka消息延迟 logstash 消费kafka消息堆积处理_kafka_10

每一个标题topic都执行以上操作,确保所有标题分区调整完毕

(10)然后和步骤8类似,同样编写partitions-topic-test.json文件定义所有标题topic的分区数和副本数的配置,确保每一个topic都有8个配置块,每个配置块有0,1,2三个副本数,代表8个分区数的副本分配情况。其中分区partition编号从0开始,副本数编号统一为0,1,2,代表每个分区的副本分散在3个Kafka节点上,形成冗余备份

logstash消费kafka消息延迟 logstash 消费kafka消息堆积处理_logstash_11

(11)之后同样使用下图中的脚本工具加载上一步中编写的json文件,调整副本数replica,之后进行确认

/usr/local/elk/src/kafka-2.4.1/bin/kafka-reassign-partitions.sh --reassignment-json-file /root/partitions-topic-test.json --zookeeper localhost:2181 --execute

 

logstash消费kafka消息延迟 logstash 消费kafka消息堆积处理_logstash_12

确认副本数调整情况:

/usr/local/elk/src/kafka-2.4.1/bin/kafka-reassign-partitions.sh --reassignment-json-file /root/partitions-topic-test.json --zookeeper localhost:2181 --verify

logstash消费kafka消息延迟 logstash 消费kafka消息堆积处理_logstash_13

(12) 现有标题topic的分区数partition和副本数replica全部调整完毕后(注意在集群的其中一台节点上执行一遍调整即可),即可重启kafka集群

 2.Logstash调优:

(1)调整logstash的标题topic分区消费策略为轮询,默认消费策略为按范围range,添加如下图箭头所示的配置段

 

logstash消费kafka消息延迟 logstash 消费kafka消息堆积处理_kafka_14

注意有多个input配置段则都需要添加上该配置段。接着调整logstash针对单个标题topic的消费线程数,这里只要保持 “logstash的个数” x “线程总数”=“单个标题topic的总分区数partition” 即可,当前有2个logstash同时工作(消费),则单个logstash的线程数调整为4。这样的配置可以使logstash消费性能达到最大。这也是开头Kafka的配置文件中分区数调整为8的原因(见Kafka调优步骤(4))。性能相关的配置项见下图箭头所示:

logstash消费kafka消息延迟 logstash 消费kafka消息堆积处理_elk_15

 修改完所有Logstash节点后,等logstash自动加载配置文件即可,若没有配置自动重载,则手动重启所有的logstash服务即可

四.调优结果:

经过调优后,消费者负载已达到均衡,采集的事件数较为接近,如下图:

logstash消费kafka消息延迟 logstash 消费kafka消息堆积处理_elk_16

最后把所有kafka节点的配置文件server.properties里的数据均衡分发时间间隔log.retention.hours还原回24小时,避免频繁触发数据同步,增加系统资源花销,影响kafka集群的正常使用,具体操作步骤详见Kafka调优中的步骤(5),最后重启整个kafka集群