bigywater.tech
Elasticsearch · 133

Thread Pool 队列与 rejected 请求

本机真实查到search线程池默认size=16、queue_size=1000且不支持动态更新,改elasticsearch.yml压缩到size=1、queue_size=1并重启后,并发20个请求真实有18个收到429的es_rejected_execution_exception,thread_pool接口上的rejected计数精确同步显示18,验证了线程池队列满载后选择快速拒绝超额请求而非无限堆积排队的真实设计。

默认search线程池
size=16, queue_size=1000,不支持动态更新
压缩到1和1后并发打20个请求
真实18个收到429,rejected计数精确同步
改回默认值重启后
rejected真实清零,size和queue_size恢复默认

做的事:本机真实查search线程池默认的size和queue_size,再真实尝试动态改queue_size看会不会被拒绝

代码GET /_cat/thread_pool/search?v PUT /_cluster/settings {"persistent":{"thread_pool.search.queue_size":5}}

验证:默认size是16、queue_size是1000;动态改queue_size真实直接被拒绝,跟write线程池是同一类不可动态更新的设置

实测 · 本机 Elasticsearch 8.15.0 执行输出
GET /_cat/thread_pool/search:
→ size: 16, queue_size: 1000, rejected: 0

动态修改queue_size: → 400 illegal_argument_exception
  "persistent setting [thread_pool.search.queue_size], not dynamically updateable"

这个真实结果跟本系列前面验证write线程池时得到的结论一致:线程池的大小和队列容量这两个设置真实都是静态配置,必须写进elasticsearch.yml并重启节点才能生效,不能在集群运行期间动态调整——这个限制对search线程池同样真实适用。

真实改elasticsearch.yml把search线程池的size和queue_size都压到1,重启生效后并发打20个请求过去

代码真实在elasticsearch.yml加两行: thread_pool.search.size: 1 thread_pool.search.queue_size: 1 真实重启节点生效 真实并发发起20个带重计算脚本的查询

验证:20个请求里真实18个收到了429状态码,thread_pool接口上的rejected计数真实精确同步显示了18

实测 · 本机执行输出
真实HTTP状态码统计: 18个429, 2个400(脚本自身撞上了Painless语句数上限,跟线程池无关)

其中一个429的真实报错原文:
→ "es_rejected_execution_exception"
→ "rejected execution of TimedRunnable{...} on
   TaskExecutionTimeTrackingEsThreadPoolExecutor[name = node-1/search,
   queue capacity = 1, ... pool size = 1, active threads = 1, queued tasks = 1]"

真实查thread_pool: → rejected: 18   ← 跟客户端收到的429数量精确对上
这组真实数据把search线程池的队列机制讲得很清楚:当size压缩到1的时候,真实同一时刻只能有1个search请求真正在执行,queue_size压缩到1意味着真实最多只能再多排1个请求等待,一旦并发请求数超过"正在执行的1个+排队的1个"这个总量,多出来的请求真实会立刻被拒绝,不会无限排队等待——这正是线程池队列设计的真实用意:宁可直接快速拒绝超额的请求,也不让它们无限堆积拖慢整个节点(这跟本系列前面验证的"master任务队列真实会无限排队、让调用方干等"是完全不同的真实处理策略,search线程池选择的是快速失败而不是让客户端干等)。

收尾:真实把配置改回默认值并重启,确认rejected计数重新清零,集群恢复到默认的16和1000

代码真实删掉yml里新加的两行,重启节点

验证:重启后真实rejected计数清零重新开始计数,size和queue_size真实都恢复到了默认的16和1000

实测 · 本机执行输出
size: 16, queue_size: 1000, rejected: 0   ← 真实全部恢复默认值

分步演示:从动态改queue_size被拒绝,到压缩线程池后真实的429拒绝与rejected计数,再到恢复默认值

每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。

线程池队列满了之后真实选择快速拒绝超额请求,而不是让它们无限堆积排队
这一步新验证的线程池队列场景

    本文用到的工具

    • 本机真实部署的 Elasticsearch 8.15.0(单节点,tar包直接启动)
    • 真实的 _cat/thread_pool API 与 thread_pool.search.size/queue_size 设置
    京ICP备2026067502号-1京公网安备11010502063487号