为什么 Elasticsearch 查询返回 429 Too Many Requests 错误

文章导读
Elasticsearch 查询返回 429 Too Many Requests 错误通常意味着集群资源已达到负载极限,请求被拒绝。主要原因包括线程池资源耗尽(如搜索或写入线程池队列满)、断路器触发(内存使用超过阈值)以及写入压力过大。解决方案包括实施指数退避重试机制、优化查询减少内存消耗、调整线程池队列大小、增加集群节点或堆内存,以及监控 indexing_pressure 等关键参数以避免资源
📋 目录
  1. A 避开 ELK 常见坑:‘Too Many Requests'报错背后的内存回收机制解析
  2. B Elasticsearch 出现"429 rejected"报错,怎么办?
  3. C elasticsearch 读写拒绝问题解析
  4. D Elasticsearch 断路器报错了,怎么办?
  5. E Elasticsearch 线程池和队列问题,请先看这一篇
  6. F FAQ
A A

Elasticsearch 查询返回 429 Too Many Requests 错误通常意味着集群资源已达到负载极限,请求被拒绝。主要原因包括线程池资源耗尽(如搜索或写入线程池队列满)、断路器触发(内存使用超过阈值)以及写入压力过大。解决方案包括实施指数退避重试机制、优化查询减少内存消耗、调整线程池队列大小、增加集群节点或堆内存,以及监控 indexing_pressure 等关键参数以避免资源争抢。

避开 ELK 常见坑:‘Too Many Requests'报错背后的内存回收机制解析

当你的 ELK 集群突然抛出"Datatoo large"的 429 错误时,背后隐藏的往往是一场关于内存管理的精密博弈。这种报错表面看是简单的资源不足,实则是 Elasticsearch 内存回收机制与查询负载之间的复杂平衡被打破的结果。本文将带你穿透表象,直击 fielddata 缓存管理的核心逻辑。1. 报错背后的内存战场 那串令人困惑的报错信息里,每个数字都在讲述一个资源争夺的故事。关键数据 fielddata=182738/178.4kb 看似不大,但结合 real usage: [2087165392/1.9gb] 就会发现,真正的战场在堆内存的全局分配。当多个分片同时执行聚合查询时,fielddata 的累积效应会像海绵吸水一样耗尽可用内存。典型的误判场景包括:低估了高基数字段 (如用户 ID、IP 地址) 聚合的内存开销 忽视了长时间运行的滚动查询对 fielddata 的累积影响 错误预估了并发查询时的内存峰值需求 提示:报错中的 bytes_wanted 值显示了当时操作需要的内存量,而 bytes_limit 则是当前断路器阈值,这两个值的差距往往就是调优的关键窗口。内存管理的关键参数对比:

Elasticsearch 出现"429 rejected"报错,怎么办?

3、"429 拒绝请求”原因解读 当 Elasticsearch 拒绝请求时,它会停止操作并返回带有 429 响应码的错误。被拒绝的请求通常由以下原因引起:原因 1:线程池资源耗尽。检索线程池或者写入线程池资源耗尽,会出现:TOO_MANY_REQUESTS 错误消息。原因 2:断路器报错,也就是内存出现熔断现象。原因 3:超过限制的写入压力。主要原因在于:将文档写入到 Elasticsearch 会以内存和 CPU 负载的形式导致系统负载升高。如果在存在过多频繁的写入操作,集群可能会变得饱和。这可能会对其他操作产生不利影响,例如搜索、集群协调和后台处理。为了防止这些问题,Elasticsearch 在内部监控索引负载。当负载超过一定限度时,新的请求将会被拒绝。写入请求最高内存上限 indexing_pressure.memory.limit 设置为堆内存的 10%。我以 elasticsearch 8.0 单节点环境作为测试:默认堆内存:4GB,未改动。上截图 limit_in_bytes = 410202931 Byte = 391.2 MB,约等于 4GB 堆内存的 10%。此外,"429 拒绝错误“可以作为衡量是否达到性能瓶颈的依据——做压力测试时可以不断增加并发,观察 CPU 使用率、磁盘 IO 使用率,当 Elasticsearch 返回 429 错误码时,可以认为 Elastic 集群达到负载极限。

elasticsearch 读写拒绝问题解析

一。什么是 elasticsearch 读写 elasticsearch 集群在某些情况下出现索引无法对索引进行查询或写入。客户端会收到 elasticsearch 返回的拒绝日志信息。二.elasticsearch 读写拒绝场景分析 1.线程池被打满导致任务堆积出现写入拒绝 代码语言:javascript AI 代码解释 org.elasticsearch.common.util.concurrent.EsRejectedExecutionException:rejected executionoforg.elasticsearch.common.util.concurrent.TimedRunnable@790ac6ff on QueueResizingEsThreadPoolExecutor[name=15xxxxxxxxx132/search,queue capacity=1000,min queue capacity=1000,max queue capacity=1000,frame size=2000,targeted response rate=1s,task executionEWMA=6.6ms,adjustment amount=50,org.elasticsearch.common.util.concurrent.QueueResizingEsThreadPoolExecutor@69e4b10[Running,pool size=13,active threads=13,queued tasks=1000,completed tasks=445155395] 1.1 elasticsearch 的线程池 在 elasticsearch 集群中,每个数据节点都会维护多个线程池来管理不同的请求的内存消耗,在线程池中许多请求可以得到保留而非直接丢弃。在 elasticsearch 的线程池中有很多线程池,例如:generic,search,search_throttled,analyze,snapshot,write 线程池。每个线程池管理不同的请求,当前我们这里遇到的是读写线程池被打满导致出现写入拒绝,所以我们这里重点关注"search thread pool"和"write thread pool"。search thread pool:搜索线程池,主要用于处理搜索类请求。一般我们可以根据集群的 (CPU 核数 * 3) / 2) + 1 来估算集群 search thread pool 的队列大小。初始化的 queue_size 为 1000; write thread pool:写入线程池,主要处理数据的写入,更新,删除等批量请求。该线程池固定队列大小的线程池,queue_size 为 10000。

为什么 Elasticsearch 查询返回 429 Too Many Requests 错误

Elasticsearch 断路器报错了,怎么办?

3、Elasticsearch 断路器报错示例 3.1 客户端请求报 429 错误 如果一个请求触发了一个断路器,Elasticsearch 会返回一个错误,其 HTTP 状态代码为 429。代码语言:javascript AI 代码解释 {'error':{'type':'circuit_breaking_exception','reason':'[parent] Data too large, data for [] would be [123848638/118.1mb], which is larger than the limit of [123273216/117.5mb], real usage: [120182112/114.6mb], new bytes reserved: [3666526/3.4mb]','bytes_wanted':123848638,'bytes_limit':123273216,'durability':'TRANSIENT'},'status':429} 熟悉 Http 协议的同学都知道:在 HTTP 协议中,响应状态码 429 Too Many Requests 表示在一定的时间内用户发送了太多的请求,即超出了“频次限制”。3.2 日志报错 Data too large elasticsearch.log 也会记录断路器错误。例如:分片的过程中会触发断路器。可能的报错如下:代码语言:javascript AI 代码解释 Caused by:org.elasticsearch.common.breaker.CircuitBreakingException:[parent]Data too large,datafor[]would be[num/numGB],which is larger than the limitof[num/numGB],usages[request=0/0b,fielddata=num/numKB,in_flight_requests=num/numGB,accounting=num/numGB]

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

问题 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 处理的速度,不过现在还没有可用环境压测,想问有经验数据或方法参考吗?问题 2:多套系统使用一套集群,错误日志如下 代码语言:javascript AI 代码解释 {"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 线程池和队列知识点。Elasticsearch 使用线程池 (Thread pool ) 来管理请求并优化集群中每个节点上的资源使用。3、线程池用途 主要线程池包括:搜索 (search)、获取 (get) 和写入 (write) 等。通过运行以下命令可以看到线程池全貌:代码语言:javascript AI 代码解释 GET/_cat/GET/_cat/thread_pool/?v&h=id,name,active,rejected,completed,size,type&pretty&s=type 其中:name:代表某一种线程池 (写入、检索、刷新或其他)。type:代表线程数类型。通过运行上面的命令可以看到每个节点都有许多不同的线程池、线程池的大小和类型,还可以看到哪些节点拒绝了操作。Elasticsearch 根据每个节点中检测到的线程数 (number of processors,后面会讲到这个参数) 自动配置线程池参数。4、线程池类型 4.1 Fixed 类型 固定数量的线程,具有固定的队列大小。Fixed 类型线程使用示例如下:代码语言:javascript AI 代码解释 thread_pool:write:size:30queue_size:1000 4.2 Scaling 类型

FAQ

429 错误是否意味着集群宕机?

为什么 Elasticsearch 查询返回 429 Too Many Requests 错误

不是,429 表示请求被拒绝但服务仍可用,通常是资源保护机制触发。

如何查看线程池拒绝次数?

为什么 Elasticsearch 查询返回 429 Too Many Requests 错误

使用 GET/_cat/thread_pool?v=true&h=id,name,queue,active,rejected,completed 命令。

遇到 429 错误应该立即重试吗?

不建议立即重试,最好实施指数退避策略以避免加剧性能问题。