ELK+Kafka优化
说明
接着上一篇的部署文章后,本篇就跟着笔者来看看相关组件的调优吧,其实优化方式可粗略分为:水平优化和垂直优化。水平优化主要就是水平扩展伸缩,通过 "量变" 达到 "质变" ;而垂直优化主要就是节省服务器资源,对服务器和部署的服务做到最大优化。
以下只是大概的优化方向,小伙伴们根据自身的实际业务环境来进行相应的优化!
硬件优化
服务组件 | CPU | 内存 | 硬盘 |
---|---|---|---|
Filebeat | 高 | 高 | 低 |
Logstash | 高 | 高 | 低 |
Kafka | 高 | 高 | 高 |
Elasticsearch | 高 | 高 | 高 |
Kibana | 高 | 高 | 低 |
对磁盘要求高的服务组件,可以选择 Raid0
或 SSD
Filebeat优化
1、源日志格式,字段数量多少,是否使用json格式提高效率
2、使用 %type 自动生成topic, 扩展kafka分区,提高kafka利用率
3、filebeat 配置文件优化
4、filebeat 源码优化
5、filebeat 正则优化,匹配日志目录尽量少使用 * 匹配
Logstash优化
1、multiple pipline 吞吐量提升
2、logstash grok 复杂度
3、logstash if 判断复杂度
4、logstash 其他 multiple 的耗时
5、更轻量的dissect
6、logstash配置文件优化
7、logstash集群化,快速读取kafka消息,快速入库es
8、JVM 内存配置
9、日志打印成JSON格式,减少logstash日志解析工作量
10、logstash pipline根据不同业务日志的大小配置 pipeline.workers,日志量大的可以调高workers数量,pipeline.batch.size也是根据日志量的大小来调整合适的值
11、pipeline.batch.delay 在分发一个batch到filters和workers之前最长等待的时间,默认是5(ms)
笔者原配:
# Logstash优化
# 适当调整logstash写入数据到es的大小(提高吞吐量):
# vi config/logstash.yml
pipeline.batch.size: 3000
pipeline.batch.delay: 200
# 说明:
# pipeline.batch.size 指发送到Elasticsearch的批量请求的大小,值越大,处理则通常更高效,但增加了内存开销;
# pipeline.batch.delay 指调整Logstash管道的延迟,过了该时间则logstash开始执行过滤器和输出。
# 修改logstash适配文件的input插件:
input {
kafka {
bootstrap_servers => "192.168.100.83:9092,192.168.100.86:9092,192.168.100.87:9092"
client_id => "chilu83"
auto_offset_reset => "latest"
consumer_threads => 12
fetch_max_wait_ms => "1000"
topics => "elk"
group_id => "chilu"
security_protocol => "SASL_PLAINTEXT"
sasl_mechanism => "PLAIN"
jaas_path => "/home/elkuser/logstash-7.2.0/config/kafka-client-jaas.conf"
}
}
# 说明:
# auto_offset_reset 指自动将偏移重置为最新的偏移量;
# consumer_threads 指Consumer线程数,一般最佳配置是同一组内consumer个数等于topic分区数,实现完美平衡,如果有多个logstash实例,就让实例个数*consumer_threads等于分区数即可;
# fetch_max_wait_ms 指当没有足够的数据立即满足fetch_min_bytes时,服务器在回答fetch请求之前将阻塞的最长时间。
Kafka优化
1、选择分区数量,每个topic分区数小于等于集群服务器数量
2、选择topic副本数
3、分区分配策略,可选择轮询
4、处理消息和磁盘IO的线程数
5、消费者组中的消费者应该等于分区数
6、删除默认的cleanup策略
笔者原配:
# 调大socket,防止报错
socket.send.buffer.bytes=1024000
socket.receive.buffer.bytes=1024000
socket.request.max.bytes=1048576000
# 使用轮询的分区分配策略
partition.assignment.strategy=roundrobin
# 修改kafka配置文件server.properties:
num.network.threads=32 # Broker处理消息的最大线程数
num.io.threads=32 # Broker处理磁盘IO的线程数
# 说明:根据cat /proc/cpuinfo | grep "processor" | wc -l配置参数!
# num.network.threads 主要处理网络io,读写缓冲区数据,基本没有io等待,配置该线程数量为cpu线程数的80%;
# num.io.threads 主要进行磁盘io操作,高峰期可能有些io等待,因此需要配置大些,配置该线程数量为cpu线程数的150%,建议不要配满!
# 删除默认的cleanup 策略,否则会造成kafka过量的数据积压!!!
bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name __consumer_offsets --describe
# 输出 Configs for topic '__consumer_offsets' are segment.bytes=104857600,cleanup.policy=compact,compression.type=producer
# 删除命令有以下三条:
bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name __consumer_offsets --alter --delete-config cleanup.policy
bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name __consumer_offsets --alter --delete-config compression.type
bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name __consumer_offsets --alter --delete-config segment.bytes
# 使用命令可以看到输出是空的,说明正确执行:
bin/kafka-configs.sh --zookeeper localhost:2181 --entity-type topics --entity-name __consumer_offsets --describe
Elasticsearch优化
1、es 分层,角色节点独立部署,冷热分离,读写分离
2、es 配置文件优化
3、系统配置文件优化
4、硬件配置,CPU,内存,SSD硬盘或者raid0
5、自定义索引模板,keyword使用
6、JVM 内存配置
7、分片的数量
8、refresh_interval 刷新间隔
9、日志保留时间,保留时间越短,查询效率越高
10、如果是多块磁盘建议写多个文件夹,加快写入速度,防止磁盘io阻塞
11、es 索引预创建
12、对于日期久远的日志可以将索引close,节约内存
13、不同索引分配不同的分片策略
14、分索引:索引越来越大,单个 shard 也很巨大,查询速度也越来越慢
15、按天为单位创建索引
16、关闭了_all及其他不必要的field以降低索引大小切关闭字段分词
17、只设置1个副本,副本分片在ES中默认配置下是以同步方式写入的,每次写入数据时当所有副本写入完成以后才返回结果,也就是说副本越多写入压力越大且耗时越长,所以设置1个副本保证最基本的容灾即可
18、 索引进行ForceMerge操作,合并分片中的segment,简单点解释就是可以把多个小文件中的数据合并到一个大文件中再进行索引排序,可明显提升查询性能
19、在服务器启动多个Data节点实例的情况下要注意一个问题,一旦服务器宕机有可能导致主从分片均不可用(主从分片被分配在同一台服务器的不同实例上了)。针对这种情况需要开启cluster.routing.allocation.same_shard.host: true 选项,禁止主从分片被分到同一台服务器上,保证服务器宕机时有副本分片可用
笔者原配:
# ES集群写入性能优化
# 在kibana界面的Dev Tools标签里,编写优化模板:
PUT /_template/myes
{
"order" : 0,
"index_patterns" : [
"*"
],
"settings" : {
"index" : {
"refresh_interval" : "30s",
"number_of_shards" : "10",
"number_of_replicas" : "1",
"translog" : {
"flush_threshold_size" : "1gb",
"sync_interval" : "30s",
"durability" : "async"
},
"merge.scheduler.max_thread_count": "1",
"merge.scheduler.max_merge_count": "100"
}
},
"mappings" : { },
"aliases" : { }
}
# 说明:
# 主分片数一般以(节点数*1.5或3倍)来计算,比如有4个节点,分片数量一般是6个到12个,每个主分片一般分配一个副本分片;
# 调整refresh_interval参数避免频繁的refresh,而生成过多的segment文件,但是会降低搜索的实时性;
# 调整translog参数降低写盘的频率,但是会降低容灾能力;
# 调整durability参数设置成async实现异步写入,flush_threshold_size可以适当调大,当translog超过该值才会触发flush;
# ES优化
# 修改elasticsearch.yml文件:
thread_pool.search.queue_size: 2000
thread_pool.write.queue_size: 300
# 说明:
# search.queue_size 指搜索队列大小
# write.queue_size 指批量写入队列大小
# 如果logstash报错:
# [2017-09-23T03:13:18,942][INFO ][logstash.outputs.elasticsearch] retrying failed action with response code: 429 ({"type"=>"es_rejected_execution_exception", "reason"=>"rejected execution of org.elasticsearch.transport.TransportService$7@7182b2b3 on EsThreadPoolExecutor[bulk, queue capacity = 200, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@3649abcf[Running, pool size = 8, active threads = 8, queued tasks = 200, completed tasks = 17677657]]"})
# 注意:提示429错误码和queue capacity信息,说明队列处理不来,写入队列已满,ES到达瓶颈!说明logstash写入到elasticsearch的速度赶不上读取数据的速度,输出数据阶段未完成的情况下,logstash仍然在不断的、快速的给ES发送bulk_reuqest,从而导致ES集群的网络io过载,elasticsearch无法继续接收数据。
# 解决方法:同时配置Logstash优化和ES优化!
Kibana优化
1、少用 * 等匹配方式
2、尽量指定字段进行匹配,而不是全文索引
3、页面刷新间隔时间一般是设置15分钟
4、es优化
5、kibana集群减轻master或client压力
6、不同的visualize,dashboard建立的视图都应该用刷新间隔至少30分钟以上Save保存,这样就不会导致每个运维打开页面后,visualize,dashboard都在实时刷新,越是查询范围广的,刷新间隔时间越要设置长,例如查全量的404,500有哪些域这种是全量查询,设置的刷新时间要更长一些