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

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
简介: Elasticsearch 断路器报错了,怎么办?

1、引言

本系列文章介绍如何修复 Elasticsearch 集群的常见错误和问题。

这是系列文章的第三篇,主要探讨:Elasticsearch 断路器报错了,怎么办?

第一篇: Elasticsearch 磁盘使用率超过警戒水位线,怎么办?

第二篇:Elasitcsearch CPU 使用率突然飙升,怎么办?

2、 啥是断路器?

断路器(circuit breakers)都指定了它可以使用内存的限制。

Elasticsearch 包含多个断路器,用于防止操作导致内存泄露错误(OutOfMemoryError)。

此外,还有一个父级断路器(parent-level breaker),规定了所有断路器可以使用的内存总量。

如果Elasticsearch估计某项操作会导致内存使用率超过断路器设置的上限,它会停止操作并返回错误。

默认情况下,父级断路器在 JVM 内存使用率达到 95% 时触发。为了防止错误,官方建议在使用率持续超过 85% 的情况下,采取措施减少内存压力。

3、Elasticsearch 断路器报错示例

3.1 客户端请求报 429 错误

如果一个请求触发了一个断路器,Elasticsearch会返回一个错误,其 HTTP 状态代码为429

{
  'error': {
    'type': 'circuit_breaking_exception',
    'reason': '[parent] Data too large, data for [<http_request>] 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 也会记录断路器错误。例如:分片的过程中会触发断路器。

可能的报错如下:

Caused by: org.elasticsearch.common.breaker.CircuitBreakingException: [parent] Data too large, data for [<transport_request>] would be [num/numGB], which is larger than the limit of [num/numGB], usages [request=0/0b, fielddata=num/numKB, in_flight_requests=num/numGB, accounting=num/numGB]

——来自《死磕Elasticsearch 知识星球》

4、检查JVM的内存使用情况

4.1 在kibana 中查看 JVM 使用率

Step1:先实现个小目标:构造1个亿+的数据

光速达成一个亿小目标,如下图所示:

step2:构造检索语句

wildcard bool 组合前缀查询语句曾经导致我线上显示环境宕机,我记忆犹新,今天就构造它!

关于 wildcard,推荐阅读:Elasticsearch 警惕使用 wildcard 检索!然后呢?

我初步构造了 bool 组合 416个(400+,416是自己随机构造的)wildcard 检索语句。

python 打印 DSL 部分截图

kibana DSL 执行类似如下截图:

DSL 部分截图

我用 python 脚本实现,这种检索非常耗时,超时时间我设置的是:20000s,确保不超时且确保可以拿回结果。

执行结果部分截图如下:

执行结果图

第一列是:评分;

第二列是:name名称(写入时随机构造生成的)。

step3:检索前观察 JVM 使用率。

22:03 分左右开始的检索,下图是开始检索前的截图,JVM Heap 使用率 13%左右。

step3:检索前观察 JVM 使用率。

执行 wildcard 前缀查询之后的召回数据前的时间段。

JVM Heap 使用率 50% 左右。

明显看到一段上升的变化曲线。

Step4:部分执行

PS:执行检索过程结果召回前的部分 Gif 动图如下:

4.2 使用命令行查看 JVM 使用率

使用 cat nodes API 来获得每个节点的当前堆内存使用率 heap.percent

GET _cat/nodes?v=true&h=name,node*,heap*

返回结果如下:

1. name    id   node.role   heap.current heap.percent heap.max
2. node-02 WCwv cdfhilmrstw        287mb           28  990.7mb

要获得每个断路器的 JVM 内存使用量,请使用节点统计 node stats  API。

GET _nodes/stats/breaker

返回结果如下:

5、如何防止断路器出错?

5.1 降低JVM的内存压力

高的 JVM 内存压力经常导致断路器错误。可能导致 JVM 使用率暴增的原因列举如下:

原因 1:分片大小设置不合理,存在过多小分片。

因为每个分片都会有内存的使用。官方建议分片大小 30GB-50GB之间。

原因 2:复杂的检索或查询操作。

举例:wildcard 查询、设置很大分桶数的聚合操作都是非常“吃”内存的,要避免。

原因 3:存在映射“爆炸”现象

定义太多的字段或将字段嵌套得太深,会导致使用大量内存的映射“爆炸”

原因 4:存在大型批量请求

大型的批量索引或多重搜索请求会造成 JVM 的内存压力。

原因 5:节点硬件资源受限

物理内存本身就很小,这种是“硬伤”,为避免后患,需要整个团队知悉并想办法协调解决。

5.2 避免在 text 类型字段上使用 fielddata

读者们还有没有印象,长津湖影评词云效果,就必须得开启 fielddata:true。

本质原因:需要对 text 字段进行聚合操作,默认 text 是做分词操作的,无法实现聚合和排序,只有 fielddata:true 开启后才可以。

但,开启 fielddate:true 会使用大量的 JVM 内存。为了避免这种情况,建议 Elasticsearch 默认在文本字段上禁用 fielddata。

官方建议:如果你已经启用了 fielddata 并触发了 fielddata 断路器,请考虑禁用它并使用关键字字段 keyword 代替。

5.3 清除 fieldata 缓存

如果你已经触发了 fielddata 断路器并且不能禁用 fielddata,需要使用清除缓存 API 来清除 fielddata 缓存。

清理缓存的命令如下:

POST _cache/clear?fielddata=true

更多缓存相关的操作,推荐阅读:

Elasticsearch 缓存深入详解

6、小结

提前知道哪些常见问题容易导致熔断器报错,能有效的指导实战工作、避免实战环境出现类似错误。

你的实战环境有没有遇到类似错误,如何解决的呢?欢迎留言交流。

参考

https://www.elastic.co/guide/en/elasticsearch/reference/current/fix-common-cluster-issues.html https://www.elastic.co/guide/en/elasticsearch/reference/current/circuit-breaker.html

推荐

1、重磅 | 死磕 Elasticsearch 方法论认知清单(2021年国庆更新版)

2Elasticsearch 7.X 进阶实战私训课(口碑不错)

3、如何系统的学习 Elasticsearch ?


更短时间更快习得更多干货!

已带领88位球友通过 Elastic 官方认证!

比同事抢先一步学习进阶干货!


相关实践学习
使用阿里云Elasticsearch体验信息检索加速
通过创建登录阿里云Elasticsearch集群,使用DataWorks将MySQL数据同步至Elasticsearch,体验多条件检索效果,简单展示数据同步和信息检索加速的过程和操作。
ElasticSearch 入门精讲
ElasticSearch是一个开源的、基于Lucene的、分布式、高扩展、高实时的搜索与数据分析引擎。根据DB-Engines的排名显示,Elasticsearch是最受欢迎的企业搜索引擎,其次是Apache Solr(也是基于Lucene)。 ElasticSearch的实现原理主要分为以下几个步骤: 用户将数据提交到Elastic Search 数据库中 通过分词控制器去将对应的语句分词,将其权重和分词结果一并存入数据 当用户搜索数据时候,再根据权重将结果排名、打分 将返回结果呈现给用户 Elasticsearch可以用于搜索各种文档。它提供可扩展的搜索,具有接近实时的搜索,并支持多租户。
相关文章
|
4天前
|
前端开发 安全 开发工具
ElasticSearch启动报错,bootstrapchecksfailed
ElasticSearch启动报错,bootstrapchecksfailed
37 0
|
4天前
|
Java Windows
windows下 安装 Elasticsearch报错warning: usage of JAVA_HOME is deprecated, use ES_JAVA_HOME
windows下 安装 Elasticsearch报错warning: usage of JAVA_HOME is deprecated, use ES_JAVA_HOME
45 0
|
4天前
|
消息中间件 监控 Java
Elasticsearch 出现 “429 rejected” 报错,怎么办?
Elasticsearch 出现 “429 rejected” 报错,怎么办?
11 0
|
4天前
|
存储 关系型数据库 API
Elasticsearch 报错index_closed_exception
`index_closed_exception` 是 Elasticsearch 中的一个异常类型,它通常发生在尝试对一个已经被关闭(closed)的索引执行搜索、写入或其他操作时。在 Elasticsearch 中,索引是用来存储和检索数据的逻辑命名空间,可以将其类比为关系型数据库中的表。
|
4天前
|
NoSQL Java Redis
Elasticsearch redis netty 报错
Elasticsearch redis netty 报错
15 0
|
11月前
|
JSON 自然语言处理 数据格式
ElasticSearch用ik_analyzer分词器出现报错
ElasticSearch用ik_analyzer分词器出现报错
158 0
|
11月前
|
Java Ruby
Error:在安装elasticsearch和logstash程序出现的报错
Error:在安装elasticsearch和logstash程序出现的报错
208 0
|
应用服务中间件 PHP nginx
Elasticsearch-PHP库使用报错:No alive nodes found in your cluster[64] in ../Elasticsearch/ConnectionPool/StaticNoPingConnectionPool.php
Hyperf Elasticsearch-PHP库使用报错:No alive nodes found in your cluster[64] in ../Elasticsearch/ConnectionPool/StaticNoPingConnectionPool.php
327 0
Elasticsearch-PHP库使用报错:No alive nodes found in your cluster[64] in ../Elasticsearch/ConnectionPool/StaticNoPingConnectionPool.php
|
Linux
ElasticSearch启动报错:unable to install syscall filter:
ElasticSearch启动报错:unable to install syscall filter:
188 0
ElasticSearch启动报错:unable to install syscall filter:
|
4天前
|
Java Maven 开发工具
【ElasticSearch 】IK 分词器安装
【ElasticSearch 】IK 分词器安装
24 1

热门文章

最新文章