当前位置: 首页>编程语言>正文

elk kafka搭建 elk与kafka



elk kafka搭建 elk与kafka,elk kafka搭建 elk与kafka_数据,第1张

作者

兴丰

阿里云Elasticsearch团队

高级开发工程师

ELK是Elasticsearch、Logstash、Kibana三大开源框架首字母大写简称,也称为Elastic Stack。Elasticsearch是一个搜索和分析引擎。Logstash是服务器端数据处理管道,能够同时从多个来源采集数据、转换数据,然后将数据发送到Elasticsearch。Kibana提供了图形和图表对数据进行可视化。用户通常在ELK前引入消息队列比如Kafka进行数据缓冲,提升系统的可靠性。

通常的系统架构和数据处理流程如下:

elk kafka搭建 elk与kafka,elk kafka搭建 elk与kafka_logstash 获取多个kafka_02,第2张

阿里云Elasticsearch已经支持完整的ELK组件一键部署,配合Kafka等消息队列,使用顺畅。

Houston, We Have A Problem

此前,某客户反馈,ES集群写入报错“es_rejected_execution_exception”,写入速度上不去,kafka堆积严重。登录监控查看后,发现ES节点的write队列堆积严重,cpu使用率很低,节点的load非常高。

elk kafka搭建 elk与kafka,elk kafka搭建 elk与kafka_elk kafka搭建_03,第3张

elk kafka搭建 elk与kafka,elk kafka搭建 elk与kafka_数据_04,第4张

首先登录ECS执行top查看cpu情况

elk kafka搭建 elk与kafka,elk kafka搭建 elk与kafka_logstash 获取多个kafka_05,第5张

各cpu wait都非常高,超过20%。

elk kafka搭建 elk与kafka,elk kafka搭建 elk与kafka_linux查看kafka状态_06,第6张

查看当前磁盘的状态,从iostat的信息来看,磁盘的写入量不高,延迟虽然稍微有点大,但基本符合预期。联系块存储的值班同学,反馈云盘的后端各项指标正常。

进一步查看load高的进程和线程是哪些。

elk kafka搭建 elk与kafka,elk kafka搭建 elk与kafka_elk kafka搭建_07,第7张

这次有了新的发现,这些线程基本都属于同一个进程,就是Elasticsearch所在的进程。这些线程都处于D状态,ps命令输出的linux的进程状态有下面几种:

D    uninterruptible sleep (usually IO)

R    running or runnable (on run queue)

S    interruptible sleep (waiting for an event to complete)

T    stopped by job control signal

t    stopped by debugger during the tracing

W    paging (not valid since the 2.6.xx kernel)

X    dead (should never be seen)

Z    defunct ("zombie") process, terminated but not reaped by its parent

linux的top命令在计算负载时包含了处于D和R状态的进程和线程,那么,load高的原因就很明确了——ES有很多线程阻塞在IO中。

真相大白

用jstack获取Es进程,随便搜了几个线程id, 发现全是write线程,而且都阻塞在translog的sync函数上。

elk kafka搭建 elk与kafka,elk kafka搭建 elk与kafka_数据_08,第8张

根据ES官方文档的介绍 ,对于每一个bulk请求,每个shard都会调用系统的fsync,保证translog持久化到磁盘上,避免硬件故障导致数据丢失。

elk kafka搭建 elk与kafka,elk kafka搭建 elk与kafka_数据_09,第9张

此问题看上去应该是每个shard每次requst分到的条数太小,频繁触发fsync导致的。用户提到logstash消费kafka然后采用bulk推送,每次3000条,每个doc 1KB大小。但是这个描述和kibana中的监控不符合,不少索引每秒只有几十篇doc写入,如果每个索引都是bulk 3000条,则曲线不会是下面这种平滑的曲线,应该是非常明显的锯齿状,波峰是3000,波谷是0。

elk kafka搭建 elk与kafka,elk kafka搭建 elk与kafka_kafka使用_10,第10张

在和用户仔细沟通后发现,所有索引的源数据都混在Kafka的同一个topic里面,logstash每次bulk数据包含几十个索引,总共上百个shard,每个shard在每次请求只能分到几十条doc,导致write线程平均每处理几十条doc就要fsync translog一次,延迟再低的SSD也支持不住。

解决方案

通常,对于一般的性能问题没有加节点解决不了的,如果有,那就升级节点规格,但费用成本较高。


临时方案


  • 调大bulk条数,控制每个请求在10MB到30MB之间,增加每次shard分到的doc条数,间接降低fsync的频率
  • 适当增加写入队列大小,避免集群偶尔抖动导致队列快速塞满而报错
  • 修改索引setting,将translog索引的刷新(flush)改为异步

修改参数如下,除了translog必须为aysnc,其他的可按需调整。

"settings": {    "index": {        "refresh_interval": "60s",        "translog": {                   "flush_threshold_size": "2gb",                   "sync_interval": "100s",                   "durability": "async"               },        "merge": {                   "policy": {                       "segments_per_tier": "30",                       "max_merged_segment": "512m"                   }               }       }}


终极方案 & 最佳实践


需要把不同索引的数据拆分到不同的Kafka topic中,和上面的临时方案结合效果更佳。

  • 避免每个shard在每次bulk请求分到的doc太少,产生频繁的fsync
  • 当上游数据产生太快,ES集群性能不足或者故障恢复、索引重建时,可以按优先级消费topic,推送指定索引到ES,提高整个系统的稳定性

实行效果

该客户采用了临时方案,吞吐很快就上去了,节点load也降下来了,kafka的堆积数据很快消费完,不再有堆积。

elk kafka搭建 elk与kafka,elk kafka搭建 elk与kafka_logstash 获取多个kafka_11,第11张

elk kafka搭建 elk与kafka,elk kafka搭建 elk与kafka_linux查看kafka状态_12,第12张

以前写入50k/s会产生瓶颈,现在峰值可达到100k/s,从cpu和磁盘io的监控来看,整体还有相当大的提升空间。

elk kafka搭建 elk与kafka,elk kafka搭建 elk与kafka_kafka使用_13,第13张

虽然translog改为异步后,写入性能得到了极大的提升,但write线程从节点队列获取每个shard的请求数据时需要加锁,每次获取数据条数太少,频繁的加锁会有不少cpu消耗在自旋锁上。如果索引按topic拆分,写入性能还将有进一步的提升。


https://www.xamrdz.com/lan/55f1934571.html

相关文章: