Elasticsearch 缓存及使用 Circuit Breaker 限制内存使用


1. Inside the JVM Heap

Elasticsearch 的缓存主要分成三大类

  • Node Query Cache (Filter Context)
  • Shard Query Cache (Cache Query 的结果)
  • Fielddata Cache
    在这里插入图片描述

2. Node Query Cache

每一个节点有一个 Node Query 缓存

  • 由该节点的所有 Shard 共享,只缓存 Filter Context 相关内容
  • Cache 采用 LRU 算法

静态配置,需要设置在每个 Data Node 上

  • Node Level - indices.queries.cache.size: ”10%” - Index Level:index.queries.cache.enabled: true

3. Shard Request Cache

缓存每个分片上的查询结果

  • 只会缓存设置了 size=0 的查询对应的结果。不会缓存 hits。但是会缓存 Aggregations 和 Suggestions

Cache Key

  • LRU 算法,将整个 JSON 查询串作为 Key,与 JSON 对 象的顺序相关

静态配置

  • 数据节点:indices.requests.cache.size: “1%”
    在这里插入图片描述

4. Fielddata Cache

除了 Text 类型,默认都采用 doc_values。节约了内存
Aggregation 的 Global ordinals 也保存在 Fielddata cache 中
Text 类型的字段需要打开 Fileddata 才能对其进行聚合和排序
Text 经过分词,排序和聚合效果不佳,建议不要轻易使用
配置
可以控制 Indices.fielddata.cache.size, 避免产生 GC (默认无限制)

5. 缓存失效

Node Query Cache
保存的是 Segment 级缓存命中的结果。Segment 被合并后,缓存会失效
Shard Request Cache
分片 Refresh 时候,Shard Request Cache 会失效。如果 Shard 对应的数据频繁发生变化,该缓存的效 率会很差
Fielddata Cache
Segment 被合并后,会失效

6. 管理内存的重要性

Elasticsearch 高效运维依赖于内存的合理分配
可用内存一半分配给 JVM,一半留给操作系统,缓存索引文件
内存问题,引发的问题
长时间 GC,影响节点,导致集群响应缓慢
OOM, 导致丢节点

7. 诊断内存状况

查看各个节点的内存状况
GET _cat/nodes?v
GET _nodes/stats/indices?pretty
GET _cat/nodes?v&h=name,queryCacheMemory,queryCacheEvictions,requestCacheMemory,reques tCacheHitCount,request_cache.miss_count
GET _cat/nodes?h=name,port,segments.memory,segments.index_writer_memory,fielddata.memo ry_size,query_cache.memory_size,request_cache.memory_size&v

8. 一些常见的内存问题

Segments 个数过多,导致 full GC

  • 现象:集群整体响应缓慢,也没有特别多的数据读写。但是发现节点在持续进行 Full G
  • 分析:查看 Elasticsearch 的内存使用,发现 segments.memory 占用很大空间
  • 解决:通过 force merge,把 segments 合并成一个
  • 建议:对于不在写入和更新的索引,可以将其设置成只读。同时,进行 force merge 操作。如
    果问题依然存在,则需要考虑扩容。此外,对索引进行 force merge ,还可以减少对 global_ordinals
    数据结构的构建,减少对 fielddata cache 的开销

Field data cache 过大,导致 full GC

  • 现象:集群整体响应缓慢,也没有特别多的数据读写。但是发现节点在持续进行 Full GC

  • 分析:查看 Elasticsearch 的内存使用,发现 fielddata.memory.size占用很大空间。同时,数据不存在写入和更新,也执行过 segments merge。

  • 解决:将 indices.fielddata.cache.size 设小,重启节点,堆内存恢复正常

  • 建议:Field data cache 的构建比较重,Elasticsearch不会主动释放,所以这个值应该设置的保守一些。如果业务上确实有所需要,可以通过增加节点,扩容解决复杂的嵌套聚合,导致集群 full GC

  • 现象:节点响应缓慢,持续进行 Full GC

  • 分析:导出 Dump 分析。发现内存中有大量 bucket 对象,查看 日志,发现复杂的嵌套聚合

  • 解决:优化聚合

  • 建议:在大量数据集上进行嵌套聚合查询,需要很大的堆内存来完成。如果业务场景确实需要。
    则需要增加硬件进行扩展。同时,为了避免这类查询影响整个集群,需要设置 Circuit Breaker 和
    search.max_buckets 的数值

9. Circuit Breaker

包含多种断路器,避免不合理操作引发的 OOM,每个断路器可以指定内存使用的限制

  • Parent circuit breaker:设置所有的熔断器可以使用的内存的总量
  • Fielddata circuit breaker:加载 fielddata 所需要的内存
  • Request circuit breaker:防止每个请求级数据结构超过一定的内存(例如聚合计算的内存)
  • In flight circuit breaker:Request 中的断路器
  • Accounting request circuit breaker:请求结束后不能释放的对象所占用的内存

10. Circuit Breaker 统计信息

GET /_nodes/stats/breaker?
  • Tripped 大于 0, 说明有过熔断
  • Limit sizeestimated size 约接近,越可能引发熔断

千万不要触发了熔断,就盲目调大参数,有可能会导致集群出问 题,也不因该盲目调小,需要进行评估
建议将集群升级到 7.x,更好的 Circuit Breaker 实现机制
增加了 indices.breaker.total.use_real_memory 配置项,可以更加精准的分析内存状况,避免 OOM

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ghostwritten

口渴,请赏一杯下午茶吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值