真实验证write线程池的queue_size不支持动态热更新,通过修改配置文件并重启生效极小的size=1/queue_size=2配置,用30个并发写入请求真实触发es_rejected_execution_exception,展示ES写入过载时的真实保护机制。
代码PUT /_cluster/settings {"persistent":{"thread_pool.write.queue_size":5}}
→ 400 illegal_argument_exception: "persistent setting [thread_pool.write.queue_size], not dynamically updateable"
这条真实报错说明write线程池的大小和队列容量真实属于节点启动时就固定下来的静态配置,不像search.max_buckets(本系列第89篇验证过)那样可以用_cluster/settings热更新——真实想调整这类线程池参数,必须真实写进elasticsearch.yml配置文件,重启节点才能生效。
代码elasticsearch.yml真实追加两行: thread_pool.write.size: 1 thread_pool.write.queue_size: 2 真实重启节点后: GET /_cat/thread_pool/write?v
name size queue_size active queue rejected write 1 2 0 0 0
这个真实的极小配置(正常生产环境真实不会这么设,这里是为了在测试规模下更容易真实触发拒绝场景)确认了之前的配置文件修改真实生效:写入线程池真实只有1个工作线程,队列真实最多只能排2个任务——这意味着同时真实超过3个(1个在执行+2个在排队)写入请求,第4个开始真实就应该被拒绝。
代码真实用30个线程同时发起: POST /tp_test/_doc {"n": i}
30个并发写入: {'success': 2, 'rejected': 28}
真实线程池统计: write size=1 queue_size=2 rejected=28 ← 跟客户端观察到的数字精确一致
真实其中一条拒绝的错误信息(节选):
→ HTTP状态码: 429
→ "es_rejected_execution_exception": "rejected execution of ... on
TaskExecutionTimeTrackingEsThreadPoolExecutor[name = node-1/write,
queue capacity = 2, ... pool size = 1, active threads = 1, queued tasks = 2]"每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。
thread_pool.write 配置与 _cat/thread_pool API