ES 分片分配(Shard Allocation)时间点:
- 初始恢复(Initial Recovery)
- 副本分配(Replica Allocation)
- 重平衡(Rebalance)
- 节点添加或移除
小结:
准备移除节点时,使用过滤器禁止路由到节点
增加新节点时,降低磁盘水位线触发重平衡,使分片分布均匀
旧节点分片不均,综合考虑每个节点分片数量和磁盘占有率调整
一. 集群级别分片分配设置
下方均为动态设置
cluster.routing.allocation.enable
不影响重启主分片恢复
all
默认primaries
只允许主分片分配new_primaries
只允许新索引的主分片none
不允许分片分配cluster.routing.allocation.node_concurrent_incoming_recoveries
- 单节点并发恢复分片请求数,默认为2。指在节点上分配目标分片
cluster.routing.allocation.node_concurrent_outgoing_recoveries
- 单节点源分片分配到新节点请求数,默认2
cluster.routing.allocation.node_concurrent_recoveries
上方两个配置的合并
cluster.routing.allocation.node_initial_primaries_recoveries
副本通过网络恢复,未分配的主分片使用本地数据恢复。此配置用于配置并行未分配主分片恢复,默认4cluster.routing.allocation.same_shard.host
禁止多个副本分片被分配到相同ip节点上
1.1 分片重平衡设置
保证分片数量在每个节点上尽可能相同。受分配过滤(Allocation Filtering)和 forced awareness 影响
cluster.routing.rebalance.enable
all
默认primaries
只允许主分片重平衡replicas
只允许副本重平衡none
cluster.routing.allocation.allow_rebalance
always
indices_primaries_active
仅当所有主分片被分配时indices_all_active
默认。仅当集群中所有分片被分配时
cluster.routing.allocation.cluster_concurrent_rebalance
1.2 分片平衡启发式(Heruistics)设置
(黑盒设置,未找到计算公式)
计算权重,根据权重从高分到低,从高的重平衡到权重低的节点,受到阈值的配置影响,低于阈值不需要重平衡(这个数值没有说明是怎么计算的)
cluster.routing.allocation.balance.shard
0.45,提升此值会使所有节点分片数量趋于平衡cluster.routing.allocation.balance.index
0.55cluster.routing.allocation.balance.threshold
1.0f, 大于0,越大则越不激进
1.3 基于磁盘的分片分配设置
通过水位线来控制重平衡
当高于洪水线(flood_stage)时,写入请求会被阻塞,只要有一个节点到达,所有节点被阻塞
当高于水位线(high watermark),ES 尝试将节点数据重平衡到其他节点
当低于水位线 (low watermark),不会触发重平衡或者重平衡将停止。同时不再向该节点派发新分片
cluster.routing.allocation.disk.threshold_enabled
启用磁盘阈值限制,默认开启cluster.routing.allocation.disk.watermark.low
最低水位线,默认85%cluster.routing.allocation.disk.watermark.low.max_headroom
默认200GBcluster.routing.allocation.disk.watermark.high
最高水位线,默认90%cluster.routing.allocation.disk.watermark.high.max_headroom
默认 150GBcluster.routing.allocation.disk.watermark.flood_stage
洪水线,默认 95%cluster.routing.allocation.disk.watermark.flood_stage.max_headroom
默认 100GBcluster.info``.update.interval
集群信息检查间隔,默认 30s
1.4 集群级别分片过滤器
上下线节点或节点处于不平衡状态时,可以通过过滤器临时阻止分片路由到该节点
PUT _cluster/settings
{
"persistent" : {
"cluster.routing.allocation.exclude._ip" : "10.0.0.1"
}
}
cluster.routing.allocation.include.{attribute}
cluster.routing.allocation.require.{attribute}
cluster.routing.allocation.exclude.{attribute}
- 属性列表:
_name
(node name),_host_ip
(node ip)_publish_ip
,_ip
(short cuts of_host_ip
and_publish_ip
), _host, _id, _tier
- 属性列表:
二. 索引分片分配设置
与集群级别一样,可以设置分片过滤器、数据层(data-tier)过滤器,但增加了每个节点的分片数设置
假设索引共 A 个节点,B 个分片,C 个副本共 BC 个分片,则每个节点最大分片数设置为 BC/A 得到最平均的分片数,(B*C/A)+1 允许节点挂掉后还有一个可以正常分配分片
index.routing.allocation.total_shards_per_node
默认不设置,可能会导致数据很不平衡
三. 实操
现象: 节点 10.15.213.12 磁盘高于 86%,虽然停止写入,但无法到达重平衡线,其他节点的分片数不均
10.15.213.12: app-es110(86.8%)
10.15.219.125: app-es 138(77.66%)
10.15.220.165: app-es 158(77.53%)
10.15.213.8: app-es 138 (69.05%)
10.15.213.9: app-es 129 (68.65%)
10.15.213.11: app-es 132 (56%)
操作: 默认水位线为 90%,降低至 85%,手动触发重平衡,重平衡完毕后再恢复设置
PUT _cluster/settings
{
"persistent": {
"cluster": {
"routing": {
"allocation.disk.watermark.low": "80%",
"allocation.allow_rebalance": "always",
"allocation.disk.watermark.high": "85%"
}
}
}
}
POST /_cluster/reroute?dry_run=false&explain=true&retry_failed=false
另外针对节点10.15.220.165 上分片较多,先计算平衡时的分片数:
- app-es 为 410 个分片,1副本,6个节点,则平均为 410*2/6=136,设置为 136+6=142
PUT clue-online-*/_settings
{
"routing": {
"allocation": {
"total_shards_per_node": 142
}
}
}
操作后:10.15.213.12 降至 83%,报警解除
四. 相关命令
// 查看未分配或待分配分片状态,如果为 STARTED 则正常,为 UNASSIGNED 异常
GET _cat/shards?h=index,shard,prirep,state,unassigned.reason
// 集群设置
GET _cluster/settings
// 解释待分配分片去向
GET _cluster/allocation/explain
PUT clue-online-*/_settings
{
"routing": {
"allocation": {
"total_shards_per_node": 142
}
}
}
// 强制 Reroute
POST /_cluster/reroute?dry_run=false&explain=true&retry_failed=false
五. 重平衡可能的问题
- 数据极速写入导致负载上升
a. 解决方式:使用写入限流器等方式控制重平衡速度 - 重平衡进入无限循环状态
a. 解决方式:检查集群整体的磁盘比例,如各分片均处在水位线附近,此问题可能出现。建议临时调整水位线,待重平衡结束后,删除不需要的数据或扩容
Ref: Cluster-level shard allocation and routing settings | Elasticsearch Guide [7.10] | Elastic