Elasticsearch
缓存及使用Circuit Breaker 限制内存使用
Inside the JVM Heap
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 .
Shard Request Cache
Fielddata Cache
-
除了Text类型,默认都采用doc_ values。 节约了内存.
- Aggregation的Global ordinals 也保存在Fielddata cache中
-
Text类型的字段需要打开Fileddata 才能对其进行聚合和排序
- Text经过分词,排序和聚合效果不佳,建议不要轻易使用
-
配置
- 可以控制Indices. fielddata. cache. size,避免产生GC (默认无限 制)
缓存失效
-
Node Query Cache
- 保存的是 Segment级缓存命中的结果。Segment 被合并后,缓存会失效
-
Shard Request Cache
- 分片Refresh 时候,Shard Request Cache 会失效。如果Shard 对应的数据频繁发生变化,该缓存的效率会很差
-
Fielddata Cache
- Segment被合并后,会失效
管理内存的重要性
- Elasticsearch 高效运维依赖于内存的合理分配
- 可用内存- -半分配给JVM, 一半留给操作系统,缓存索引文件
- 内存问题, 引发的问题
- 长时间GC, 影响节点,导致集群响应缓慢
- OOM, 导致丢节点.
诊断内存状况
- 查看各 个节点的内存状况
- GET . _cat/nodes?v
- GET nodes/stats/ indices?pretty
- GET
cat/nodes?v&h=name, queryCacheMemory, queryCacheEv ictions, reques tCacheMemory, requestCacheHi tCount, request cache. miss count - GET
cat/ nodes?h=name, port, segments. memory, segments. index writer memory, fielddata. memory_ size, query_ cache. memory size, request cache. memory size&v
一些常见的内存问题
Segments 个数过多,导致ful1 GC
-
现象: 集群整体响应缓慢,也没有特别多的数据读写。但是发现节点在持续进行Full GC
-
分析: 查看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的数值
Circuit Breaker
- 包含多种断路器,避免不合理操作引发的OOM,每个断路器可以指定内存使用的限制
- Parent circuit breaker:设置所有的熔断 器可以使用的内存的总量
- Fielddata circuit breaker: 加载fielddata 所需要的内存
- Request circuit breaker: 防止每个请求级数据结构超过一- 定的内存( 例如聚合计算的内存)
- In flight circuit breaker: Request中的断路器
- Accounting request circuit breaker: 请求结束后不能释放的对象所占用的内存
Circuit Breaker 统计信息
监控Elasticsearch 集群
Elasticsearch Stats 相关的API
- Elasticsearch 提供了多个监控相关的API
- Node Stats:_ nodes/stats
- Cluster Stats:_ _cluster/stats .
- Index Stats: index_ name/_ stats
Elasticsearch Task API
-
查看 Task相关的API
- Pending Cluster Tasks API: GET_ cluster/pending_ _tasks
- Task Management API :GET_ _tasks (可以用来Cancel 一个Task)
-
监控Thread Pools
- GET_ nodes/ thread_ _pool
- GET _ nodes/stats/ thread. _pool
- GET_ cat/thread_ pool?v
- GET . nodes/hot threads
The Index &Query Slow Log
如何创建监控Dashboard
- 开发 Elasticsearch plugin, 通过读取相关的监控API, 将数据发送到ES,或者TSDB
- 使用 Metricbeats 搜集相关指标
- 使用 Kibana或Grafana创建Dashboard
- 可以开发 Elasticsearch Exporter, 通过Prometheus 监控Elasticsearch 集群
demo API
# Node Stats:
GET _nodes/stats
#Cluster Stats:
GET _cluster/stats
#Index Stats:
GET kibana_sample_data_ecommerce/_stats
#Pending Cluster Tasks API:
GET _cluster/pending_tasks
# 查看所有的 tasks,也支持 cancel task
GET _tasks
GET _nodes/thread_pool
GET _nodes/stats/thread_pool
GET _cat/thread_pool?v
GET _nodes/hot_threads
GET _nodes/stats/thread_pool
# 设置 Index Slowlogs
# the first 1000 characters of the doc's source will be logged
PUT my_index/_settings
{
"index.indexing.slowlog":{
"threshold.index":{
"warn":"10s",
"info": "4s",
"debug":"2s",
"trace":"0s"
},
"level":"trace",
"source":1000
}
}
# 设置查询
DELETE my_index
//"0" logs all queries
PUT my_index/
{
"settings": {
"index.search.slowlog.threshold": {
"query.warn": "10s",
"query.info": "3s",
"query.debug": "2s",
"query.trace": "0s",
"fetch.warn": "1s",
"fetch.info": "600ms",
"fetch.debug": "400ms",
"fetch.trace": "0s"
}
}
}
GET my_index