Elasticsearch 线程池和队列问题,请先看这一篇-阿里云开发者社区

开发者社区> laoyang360> 正文

Elasticsearch 线程池和队列问题,请先看这一篇

简介: 1、线程池相关线上实战问题 问题1:从Kafka消费数据导入 elasticsearch 时,批量 bulk 写入抛异常被拒绝。ES 集群四个节点,其中:两个节点node1和node4 thread pool bulk rejected 30多万条数据,es bulk thread pool 线程数8、队列200, Kafka写线程池 thread数2*cores+cores/2、队列数3。目前是想平衡一下写的速度和 es 处理的速度,不过现在还没有可用环境压测,想问有经验数据或方法参考吗?
+关注继续查看

image.png

链接

问题2:多套系统使用一套集群,错误日志如下


{"message": "failed to execute pipeline for a bulk request" ,

"stacktrace": ["org.elasticsearch.common.util.concurrent.EsRejectedExecutionException: rejected execution of org.elasticsearch.ingest.IngestService$4@5b522103 on EsThreadPoolExecutor[name = node-2/write, queue capacity = 1024, org.elasticsearch.common.util.concurrent.EsThreadPoolExecutor@19bdbd79[Running, pool size = 5, active threads = 5, queued tasks = 1677, ]]",

针对问题 2,初步排查日志,是大量日志写入造成队列满了,造成集群直接拒绝写入了。


问题 2 初步解决方案:修改默认值、扩大队列,根据业务后续持续观察队列大小,不再出现上述情形。


问题 1、2 都会引出:Elasticsearch 线程池和队列知识点。


2、线程池概览

Elasticsearch 使用线程池(Thread pool )来管理请求并优化集群中每个节点上的资源使用。


3、线程池用途

主要线程池包括:搜索(search)、获取(get)和写入(write)等。


通过运行以下命令可以看到线程池全貌:


GET /_cat/GET /_cat/thread_pool/?v&h=id,name,active,rejected,completed,size,type&pretty&s=type

image.png

其中:


name:代表某一种线程池(写入、检索、刷新或其他)。


type:代表线程数类型。


通过运行上面的命令可以看到每个节点都有许多不同的线程池、线程池的大小和类型,还可以看到哪些节点拒绝了操作。


Elasticsearch根据每个节点中检测到的线程数(number of processors,后面会讲到这个参数)自动配置线程池参数。


4、线程池类型

4.1 Fixed 类型

固定数量的线程,具有固定的队列大小。


Fixed 类型线程使用示例如下:


thread_pool:

   write:

       size: 30

       queue_size: 1000

4.2 Scaling 类型

可变数量的线程,Elasticsearch会根据工作负载自动调节线程大小(值介于:core 到 max 之间)。


Scaling 类型线程使用示例如下:


thread_pool:

   warmer:

       core: 1

       max: 8

4.3 fixed_autoqueue_size 线程

固定数量的线程,队列大小会动态变化以保持目标响应时间。


该功能 8.0+ 版本会废弃,这里也不着重讲解。


fixed_autoqueue_size 类型线程使用示例如下:


强调了队列大小可变。


thread_pool:

   search:

       size: 30

       queue_size: 500

       min_queue_size: 10

       max_queue_size: 1000

       auto_queue_frame_size: 2000

       target_response_time: 1s

5、线程池使用举例

若要查看哪些线程 CPU 利用率高或花费的时间最长,可以使用以下查询。


GET /_nodes/hot_threads

该 API 有助于排查性能问题。


更多推荐:深入解读 Elasticsearch 热点线程 hot_threads


6、线程池和队列认知

认知 1:必要时设置:processors

值得注意的是,线程池是根据 Elasticsearch 在基础硬件上检测到的线程数(number of processors)设置的。


如果检测失败,则应在 elasticsearch.yml 中显式设置硬件中可用的线程数。


特别是在一台宿主机配置多个 Elasticsearch 节点实例的情况下,若要修改其中一个节点线程池或队列大小,则要考虑配置 processors 参数。


elasticsearch.yml 中设置如下所示:


processors: 4

PS:Linux 查看线程数方法:


grep 'processor' /proc/cpuinfo | sort -u | wc -l

认知 2:线程池关联队列设置

大多数线程池还具有与之关联的队列,以使 Elasticsearch 可以将请求存储在内存中,同时等待资源变得可用来处理请求。


但是,队列通常具有有限的大小,如果超过该大小,Elasticsearch将拒绝该请求。


认知 3:很糟糕做法——盲目修改队列大小

有时你可能会增加队列的大小以防止请求被拒绝,但要结合资源实际进行修改,千万别盲目修改。


实际上,如果值设置的非常大,甚至可能适得其反。因为通过设置更大的队列大小,该节点将需要使用更多的内存来存储队列,这就意味着将剩下相对较少的内存来响应和管理实际请求。


此外,增加队列大小还会增加将操作响应保留在队列中的时间长度,从而导致客户端应用程序面临超时问题。


以下的莽撞行为,大家是要实战中避免的。

认知 4:加强监控

通常,唯一有需要增加队列大小的情况是:在请求数量激增导致无法在客户端管理此过程且资源使用率并未达到峰值。


你可以借助 Kibana Stack Monitoring 可视化监控指标以更好地了解 Elasticsearch 集群的性能。


Kibana 监控面板中的总视图、节点视图、索引视图如下所示:


总视图监控

image.png

  • 节点视图监控

image.png

image.png

  • 索引视图监控

image.png

上图是:Kibana 7.6 版本中的监控截图,标红的地方是我在批量写入数据。


search Rate:检索速率


search Latency:检索延时


indexing Rate:写入速度


indexing Latency:写入延时


队列的增加(Growing)表明 Elasticsearch难以满足请求,而拒绝(rejection)则表明队列已经增长到 Elasticsearch 拒绝的程度。


需要检查导致队列增加的根本原因,并尝试通过在客户端减轻相关写入或检索操作来平衡对集群线程池的压力。


7、线程池线上实战问题及注意事项

7.1 线程池和队列修改需要更改配置文件 elasticsearch.yml

节点级别配置,而不再支持 5.X 之前的版本动态 setting 修改。


重启集群后生效。


7.2 reject 拒绝请求的原因有多种

类似文章开头问题 2,如果 Elasticsearch 集群开始拒绝索引/写入(index)请求,则可能有多种原因。


通常,这表明一个或多个节点无法跟上索引 / 删除 / 更新 / 批量请求的数量,从而导致在该节点上建立队列且队列逐渐累积。


一旦索引队列超过队列的设置的最大值(如 elasticsearch.yml 定义的值或者默认值),则该节点将开始拒绝索引请求。


排查方法:需要检查线程池的状态,以查明索引拒绝是否总是在同一节点上发生,还是分布在所有节点上。


GET /_cat/thread_pool?v

如果 reject 仅发生在特定的数据节点上,那么您可能会遇到负载平衡或分片问题。


如果 reject 与高 CPU 利用率相关联,那么通常这是 JVM 垃圾回收的结果,而 JVM 垃圾回收又是由配置或查询相关问题引起的。


如果集群上有大量分片,则可能存在过度分片的问题。


如果观察到节点上的队列拒绝,但监控发现 CPU 未达到饱和,则磁盘写入速度可能存在问题。


7.3 写入 bulk 值要递进步长调优

不要妄图快速提高写入速度,一下调很大,很大势必会写入 reject。


首先尝试一次索引 100 个文档,然后索引 200 个,再索引 400 个,依此类推......


当索引写入速度(indexing rate)开始趋于平稳时,便知道已达到数据批量请求的最佳大小。


8、小结

写入 reject、“429  too many requests” 等都是非常常见的错误,问题多半和线程池和队列大小有关系,需要结合业务场景进行问题排查。


本文“抛砖引玉”,给出线程池和队列相关总结知识。您在实战中遇到的类似问题吗?欢迎留言探讨交流。


参考

https://drscg.tistory.com/640


https://opster.com/elasticsearch-glossary/index-queue-size-is-high/


https://opster.com/elasticsearch-glossary/elasticsearch-threadpool/


https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-threadpool.html


https://opster.com/analysis/elasticsearch-requested-thread-pool-size-for-is-too-large-setting-to-maximum-instead/


推荐:


全网首发!《 Elasticsearch 最少必要知识教程 V1.0 》低调发布


从实战中来,到实战中去——Elasticsearch 技能更快提升方法论


Elasticsearch写入原理深入详解


Elasticsearch性能优化实战指南


让Elasticsearch飞起来!——性能优化实践干货

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
用它解决大问题啦,STRACE应用
脚本是沙沙,辉哥和我在去年解决一个PHP时弄出来的。。。强! 简单而实用。 抓到的TRC文件放在TRC目录下。 如果有异常的进程或输出,可以在里面详细的分析。。   #!/bin/bash mkdir trc rm -rf trc/*.
761 0
阿里云服务器如何登录?阿里云服务器的三种登录方法
购买阿里云ECS云服务器后如何登录?场景不同,大概有三种登录方式:
2509 0
Linux问题情报分享(1):内核Stack Clash补丁导致Java程序启动失败
突然发现Java程序无法启动。或者内核升级后Java程序无法启动。那么,很可能是内核Stack Clash补丁导致的。
2434 0
阿里云服务器端口号设置
阿里云服务器初级使用者可能面临的问题之一. 使用tomcat或者其他服务器软件设置端口号后,比如 一些不是默认的, mysql的 3306, mssql的1433,有时候打不开网页, 原因是没有在ecs安全组去设置这个端口号. 解决: 点击ecs下网络和安全下的安全组 在弹出的安全组中,如果没有就新建安全组,然后点击配置规则 最后如上图点击添加...或快速创建.   have fun!  将编程看作是一门艺术,而不单单是个技术。
8947 0
记一次典型的TCP传输吞吐效率问题
客户在ECS上实现了一个供小图片上传的接口,通过高防->SLB->ECS的网络链路将接口发布给终端用户,但是发现上传的速率很不理想。初看起来像是高防问题,但是通过排查最终发现这是一个典型的TCP传输吞吐量问题,并且是由于后端服务器端的配置而引起,在此记录下排查过程和相关原理。
6851 0
+关注
348
文章
0
问答
文章排行榜
最热
最新
相关电子书
更多
《Nacos架构&原理》
立即下载
《看见新力量:二》电子书
立即下载
云上自动化运维(CloudOps)白皮书
立即下载