bulk写es超时问题

背景

笔者维护的线上EFK集群,在天天早上8点建立新索引的时候,日志中总会出现以下的日志:html

failed to process cluster event (cluster_update_settings) within 30s
[2019-04-13T08:00:38,213][DEBUG][o.e.a.b.TransportShardBulkAction] [logstash-felice-query-2019.04.13][2] failed to execute bulk item (index) BulkShardRequest [[logstash-felice-query-2019.04.13][2]] containing [7] requests
org.elasticsearch.cluster.metadata.ProcessClusterEventTimeoutException: failed to process cluster event (put-mapping) within 30s
        at org.elasticsearch.cluster.service.MasterService$Batcher.lambda$onTimeout$0(MasterService.java:124) ~[elasticsearch-6.3.0.jar:6.3.0]
        at java.util.ArrayList.forEach(ArrayList.java:1257) ~[?:1.8.0_152]
        at org.elasticsearch.cluster.service.MasterService$Batcher.lambda$onTimeout$1(MasterService.java:123) ~[elasticsearch-6.3.0.jar:6.3.0]
        at org.elasticsearch.common.util.concurrent.ThreadContext$ContextPreservingRunnable.run(ThreadContext.java:625) ~[elasticsearch-6.3.0.jar:6.3.0]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [?:1.8.0_152]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [?:1.8.0_152]
        at java.lang.Thread.run(Thread.java:748) [?:1.8.0_152]

问题缘由

简言之:es的master处理不过来了,es的segment合并是一个很是耗时的操做。
批量处理的超时时间默认设置为30s。
能够经过如下命令查看pending的task:java

curl 'localhost:9200/_cat/pending_tasks?v'

网上说法不一,出现这个问题极可能的缘由能够总结以下:git

  1. 分片数过多;单节点的分片数不要超过1000个(经验值);
  2. 经过写入数据自动建立索引最容易出现这种状况;
  3. 大批量写入数据refresh时间间隔过短;
  4. 索引的字段数量太多(几十上百个)

解决方案

方案一:天天预建立索引

虽然普通的EFK日志服务能够经过logstash的默认模板去建立索引,可是当索引个数比较大,而且索引的字段数量太多时,就很是容易出现超时。那么咱们通常的作法是提早建立好索引,而且设定好每一个索引的mapping。
笔者采用了一种偷懒的操做,写了一个定时任务,天天去读取当天的索引的mapping,而后直接用这个mapping去建立新的索引。固然这种解决方案的前提是你本身已经对索引有了一个基本的管理。github

方案二:减小每一个节点的分片数

es默认为每一个索引设置的分片数是5。能够经过如下命令查看索引的settings:app

GET /logstash-sonofelice-2019.04.27

能够在建立索引的时候,优化一下分片的个数。能够参考文章:https://www.cnblogs.com/gugul...
一句话:shard越少越好。shard越少,越能减小写入开销。curl

方案三:集群扩容

若是是偶发性的写入超时,多是流量高峰或者新建立索引的时候建立mapping新字段致使。
可是若是常常性的出现超时,而且write_queue里面的数据太多,cpu使用率居高不下,那可能就是es集群出现了瓶颈,这时候就须要进行扩容,没有更好的办法。elasticsearch

参考资料

https://github.com/elastic/el...优化