Elasticsearch 拒绝请求时,会停止该操作,并返回 HTTP 429 状态码,表示 TOO_MANY_REQUESTS。HTTP 响应正文会说明拒绝原因。可以重试 HTTP 429 错误,但一般应使用指数退避,避免进一步加重性能问题。
检查被拒绝的任务
请求被拒绝往往是资源耗尽造成的,以下介绍最常见的原因。
查看线程池
使用 cat thread pool API 检查每个线程池被拒绝的任务数量:
GET /_cat/thread_pool?v=true&h=id,name,queue,active,rejected,completed
如果 rejected 相对于 completed 的比例很高,尤其是在 search 和 write 线程池中,说明 Elasticsearch 经常拒绝请求。
下面是典型的队列容量错误。API 响应正文返回 es_rejected_execution_exception:
{
"shard" : 0,
"node" : "XXXX",
"reason" : {
"reason" : "rejected execution of org.elasticsearch.common.util.concurrent.TimedRunnable@26c03d4a on QueueResizingEsThreadPoolExecutor[name = XXXXX/search, queue capacity = 1000, min queue capacity = 1000, max queue capacity = 1000, frame size = 2000, targeted response rate = 1s, task execution EWMA = 968.1ms, adjustment amount = 50, org.elasticsearch.common.util.concurrent.QueueResizingEsThreadPoolExecutor@70be0765[Running, pool size = 25, active threads = 25, queued tasks = 1000, completed tasks = 616499351]]",
"type" : "es_rejected_execution_exception"
},
"index" : "my-index-000001"
}
错误日志则返回 EsRejectedExecutionException:
Caused by: org.elasticsearch.common.util.concurrent.EsRejectedExecutionException: rejected execution of org.elasticsearch.common.util.concurrent.TimedRunnable@1a25fe82 on QueueResizingEsThreadPoolExecutor[name = XXXXX/search, queue capacity = 1000, min queue capacity = 1000, max queue capacity = 1000, frame size = 2000, targeted response rate = 1s, task execution EWMA = 10.7ms, adjustment amount = 50, org.elasticsearch.common.util.concurrent.QueueResizingEsThreadPoolExecutor@6312a0bb[Running, pool size = 25, active threads = 25, queued tasks = 1000, completed tasks = 616499351]]
如果线程池拒绝错误持续发生,请排查线程池导致的任务队列积压。完整演示见线程池拒绝问题视频。
检查熔断器
使用节点统计 API 检查熔断器触发次数:
GET /_nodes/stats/breaker
这些统计自节点启动以来累计。更多信息见熔断器错误相关文档,也可观看熔断器错误排查视频。
分析索引压力
Elasticsearch 会预留部分 JVM 内存用于索引。如果堆使用量超过 indexing_pressure.memory.limit,就可能产生错误。通过节点统计 API 查看索引压力拒绝次数:
GET _nodes/stats?human&filter_path=nodes.*.indexing_pressure
这些统计也是自节点启动以来累计。
以下示例展示索引压力导致的拒绝。API 响应正文返回 es_rejected_execution_exception:
{
"error" : {
"root_cause" : [
{
"type" : "es_rejected_execution_exception",
"reason" : "rejected execution of primary operation [coordinating_and_primary_bytes=XXXXX, replica_bytes=XXXXX, all_bytes=XXXXX, coordinating_operation_bytes=XXXXX, max_coordinating_and_primary_bytes=XXXXX]"
}
],
"type" : "es_rejected_execution_exception",
"reason" : "rejected execution of coordinating operation [coordinating_and_primary_bytes=XXXXX, replica_bytes=XXXXX, all_bytes=XXXXX, coordinating_operation_bytes=XXXXX, max_coordinating_and_primary_bytes=XXXXX]"
},
"status" : 429
}
错误日志返回 EsRejectedExecutionException:
Caused by: org.elasticsearch.common.util.concurrent.EsRejectedExecutionException: rejected execution of primary operation [coordinating_and_primary_bytes=XXXXX, replica_bytes=XXXXX, all_bytes=XXXXX, coordinating_operation_bytes=XXXXX, max_coordinating_and_primary_bytes=XXXXX]
按照文档读写模型,错误中的 rejected execution of <category> operation 会指出以下类别之一:combined_coordinating_and_primary、coordinating、primary 或 replica。
这些错误通常与以下情况有关:
- 积压任务的数量。
- 批量索引的批次设置过大。
- 搜索响应体过大。
- 使用
semantic_text字段类型。对大批量文档建立索引时,如果继续处理可能导致内存不足(OOM),系统可能会拒绝请求。
排查演示见索引压力拒绝视频。
避免请求被拒绝
使用 AutoOps 检测并解决问题
AutoOps 是监控工具,能够实时检测 Elasticsearch 集群问题,并建议如何解决及改善性能。
解决 CPU 与内存使用率过高的问题
如果 Elasticsearch 经常拒绝请求和其他任务,集群很可能存在高 CPU 使用率或高 JVM 内存压力。可以参阅相应的高 CPU 使用率与高 JVM 内存压力排查文档。
解决 semantic_text 摄取问题
批量索引具有 semantic_text 字段的文档时,推理处理可能消耗过多内存,从而导致请求被拒绝。这些拒绝会在集群日志中表现为 InferenceException。
处理步骤:
- 减小索引请求中的文档批次。
- 如果缩小批次仍无法解决,考虑增加机器资源。
最后手段是调整集群设置 indexing_pressure.memory.coordinating.limit。默认值为堆内存的 10%。提高该限制,允许协调操作在被拒绝之前使用更多内存。
警告:只有其他方案都已尝试后,才应考虑调整这一值。设置过高可能让集群发生内存不足错误。修改后必须重启集群才会生效。
原文:Rejected requests。作者/维护方:Elastic 文档维护者。本文为中文翻译,代码及命令保留原文。











暂无评论内容