节点熔断的含义
Elasticsearch Service 提供了多种官方的熔断器(circuit breaker),用于防止内存使用过高导致 ES 集群因为 OutOfMemoryError 而出现问题。每个熔断器都指定了它可以使用多少内存的限制。此外,还有一个父级熔断器,它指定可以跨所有熔断器使用的内存总量。
官方熔断机制的一个不足是仅跟踪那些经常会出问题的请求来预估内存的使用,而无法根据当前节点的实际内存使用状态,来限制请求的内存使用或触发熔断。在腾讯云 ES 中,开发了针对 JVM OLD 区内存使用率的自研熔断器来解决这个问题。
腾讯云 ES 的自研熔断器监控 JVM OLD 区的使用率,当节点使用率超过85%
时开始拒绝写入请求,若 GC 仍无法回收 JVM OLD 区中的内存,在节点使用率到达90%
时将拒绝查询请求
定位节点熔断的原因
1、判断当前节点熔断的情况
监控项“集群熔断次数”可直观查看到集群是否发生了熔断,old gc 次数也可以反映出集群熔断情况
日志中可查询到“data toor large"关键字
2、定位集群熔断可能的原因
(1)出现请求突增
(2)有大聚合或者时间跨度大的查询
(3)磁盘利用率超水位
根据相应的问题提供解决方案
1、出现请求突增
通常是有查询请求突增引发熔断,针对读多写少的场景,可以:
1.严格遵循索引单分片30g~50g的设计原则;
2.在遵循单分片设计原则的前提下,预测出索引最终大小,并根据集群节点数设计索引分片数量,使分片尽量平均分布在各个节点;
3.条件允许的情况下可设置更多的副本分片分担查询压力;
4.设置集群冷热分离,对于部分查询实时性要求不高的索引数据,可定期迁移至冷节点,尽可能提升热节点的规格。
2、优化查询语句
1.避免查询 all 索引;
2.避免使用多索引的关联查询方式,尽可能在初始时设计好数据结构;
3.避免使用多层嵌套查询,或者复杂的查询操作,比如 join、nested、parent-child 等等
3、磁盘利用率超水位
定期进行磁盘清理或扩容磁盘
熔断日志解读
代码语言:javascript复制[o.e.m.j.JvmGcMonitorService] [1576592439000051711] [gc][16309166] overhead, spent [869ms] collecting in the last [1.3s]
以上日志表示,集群在最近1.3s 内花费869ms 做 gc 收集,检查时间和占比都在正常范围内
代码语言:javascript复制[o.e.m.j.JvmGcMonitorService] [1576592439000051711] [gc][young][16309166][2415160] duration [869ms], collections [1]/[1.3s], total [869ms]/[17.4h], memory [11.7gb]->[11gb]/[15.8gb], all_pools {[young] [730.1mb]->[2.9mb]/[865.3mb]}{[survivor] [83.9mb]->[84.7mb]/[108.1mb]}{[old] [10.9gb]->[10.9gb]/[14.9gb]}
以上日志分段解读
[gc][young][16309166][2415160] duration [869ms], collections [1]/[1.3s],本次进行新生代回收,是第16309166次检查,从 jvm 启动至今的第2415160次,总耗时869ms,从上次检查至今已有1次,已过去1.3s;
memory [11.7gb]->[11gb]/[15.8gb],所有内存在回收前是11.7gb,回收后是11gb,总内存为15.8gb;
{[young] [730.1mb]->[2.9mb]/[865.3mb]},young 区在回收前是730.1mb,回收后是2.9mb,young 区的总内存为865.3mb;
{[survivor] [83.9mb]->[84.7mb]/[108.1mb]}{[old] [10.9gb]->[10.9gb]/[14.9gb]},survivor 和 old 区在经过回收后,内存基本不变,是因为内存是在 young 区多轮回收后进入 survivor,survivor 满后进入 old 区