高可用 Elasticsearch 集群的分片管理 (Shard)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高可用 Elasticsearch 集群的分片管理 (Shard)相关的知识,希望对你有一定的参考价值。

参考技术A

一个 shard 本质上就是一个 Lucene 索引,也是 Elasticsearch 分布式化 Lucene 的关键抽象,是 Elasticsearch 管理 Lucene 文件的最小单位。

所以,Elasticsearch 提供了大量的接口,可以对集群内的 shard 进行管理。

将分片从一个节点移动到另一个节点,在使用 Elasticsearch 中,鲜有需要使用该接口去移动分片,更多的是使用 AllocationDecider 参数以及平衡参数去自动调整 shard 的位置。

在一些特别的情况下,例如发现大部分热点数据集中在几个节点,可以考虑手工 move 一下。

explain api 是 Elasticsearch 5.x 以后加入的非常实用的运维接口,可以用来诊断 shard 为什么没有分配,以及 shard 为什么分配在某个节点。

如果不提供参数调用该 api,Elasticsearch 返回第一个 unassigned shard 未分配的原因。

在索引过程中,Elasticsearch 首先在 primary shard 上执行索引操作,之后将操作发送到 replica shards 执行,通过这种方式使 primary 和 replica 数据同步。

对于同一个分片的所有 replicas,Elasticsearch 在集群的全局状态里保存所有处于同步状态的分片,称为 in-sync copies。

如果修改操作在 primary shard 执行成功,在 replica 上执行失败,则 primary 和 replica 数据就不在同步,这时 Elasticsearch 会将修改操作失败的 replica 标记为 stale,并更新到集群状态里。

当由于某种原因,对于某个 shard 集群中可用数据只剩 stale 分片时,集群会处于 red 状态,并不会主动将 stale shard 提升为 primary shard,因为该 shard 的数据不是最新的。这时如果不得不将 stale shard 提升为主分片,需要人工介入:

当由于 lucene index 损坏或者磁盘故障导致某个分片的主副本都丢失时,为了能使集群恢复 green 状态,最后的唯一方法是划分一个空 shard。

一定要慎用该操作,会导致对应分片的数据完全清空。

一般来说,增加主分片数量可以增加写入速度和查询速度,因为数据分布到了更多的节点,可以利用更多的计算和 IO 资源。增加副分片数量可以提升查询速度,并发的查询可以在多个分片之间轮询。

但是 shard 管理并不是 “免费” 的,shard 数量过多会消耗更多的 cpu、内存资源,引发一系列问题,主要包括如下几个方面。

任一时刻,一个集群中只有一个节点是 master 节点,master 节点负责维护集群的状态信息,而且状态的更新是在单线程中运行的,大量的 shard 会导致集群状态相关的修改操作缓慢,比如创建索引、删除索引,更新 setting 等。

单个集群 shard 超过 10 万,这些操作会明显变慢。集群在恢复过程中,会频繁更显状态,引起恢复过程漫长。

我们曾经在单个集群维护 30 多万分片,集群做一次完全重启有时候需要2-4个小时的时间,对于业务来说是难以忍受的。

查询很多小分片会降低单个 shard 的查询时间,但是如果分片过多,会导致查询任务在队列中排队,最终可能会增加查询的整体时间消耗。

Elasticsearch 协调节点接收到查询后,会将查询分发到查询涉及的所有 shard 并行执行,之后协调节点对各个 shard 的查询结果进行归并。

如果有很多小分片,增加协调节点的内存压力,同时会增加整个集群的 cpu 压力,甚至发生拒绝查询的问题。因为我们经常会设置参与搜索操作的分片数上限,以保护集群资源和稳定性,分片数设置过大会更容易触发这个上限。

Elasticsearch 通过 AllocationDecider 策略来控制 shard 在集群内节点上的分布。

分片平衡对 Elasticsearch 稳定高效运行至关重要。下面介绍 Elasticsearch 提供的分片平衡参数。

当使用 cluster.routing.allocation.balance.shard 和 index.routing.allocation.total_shards_per_node 不能使分片平衡时,就需要通过该参数来控制分片的分布。

所以,我们的经验是: 创建索引时,尽量将该值设置的小一些,以使索引的 shard 比较平均的分布到集群内的所有节点。

但是也要使个别节点离线时,分片能分配到在线节点,对于有 10 个几点的集群,如果单个索引的主副本分片总数为 10,如果将该参数设置成 1,当一个节点离线时,集群就无法恢复成 Green 状态了。

所以我们的建议一般是保证一个节点离线后,也可以使集群恢复到 Green 状态。

Elasticsearch 内部的平衡策略都是基于 shard 数量的,所以在运行一段时间后,如果不同索引的 shard 物理大小差距很大,最终会出现磁盘使用不平衡的情况。

所以,目前来说避免该问题的以办法是让集群内的 shard 物理大小尽量保持相近。

主节点对 shard 的管理是一种代价相对比较昂贵的操作,因此在满足需求的情况下建议尽量减少 shard 数量,将分片数量和分片大小控制在合理的范围内,可以避免很多问题。

下一节我们将介绍 分片内部的段合并 相关问题。

以上是关于高可用 Elasticsearch 集群的分片管理 (Shard)的主要内容,如果未能解决你的问题,请参考以下文章

Elasticsearch 快照生命周期管理 (SLM) 实战指南

elasticsearch高可用 原理

Elasticsearch 7.x 之节点集群分片及副本

5.elasticsearch-分片

ElasticSearch集群

ElasticSearch之二——集群