
分片分配就是把一个分片分配到某个节点的过程。我们在创建或删除索引、节点加入、节点离线、执行reroute API、调整副本数、集群重启等场景下都需要用到分片分配。
分片分配可以拆解成两个问题
1、选择一个合适的节点分配分片
2、确定该节点上的分片是主分片还是副本
Elasticsearch通过Allocator和AllocationDecider两类基础组件完成分片分配过程。其中Allocator负责找到最合适的分配节点;AllocationDecider负责判断这个节点是否能够分配该分片。
对于已经存在的索引和新建索引处理方式也有差异:
1、新建索引场景:
在新建索引的场景下,Allocator会根据负载均衡权重算法对集群所有数据节点进行排序。一般情况下节点上分片数量越少,越靠前(具体排序算法见后面章节),目标是将新索引的所有分片更均衡的分配在集群中。
在Allocator对数据节点列表排序基础上,AllocationDecider遍历该节点列表,依次匹配该组件所有16种Decider,每种Decider包含检验该分片是否能够分配在该节点的方法。
2、已有索引场景:
如果不是新建索引场景,即集群原本已分配过该索引分片,后来由于节点离开、集群重启等原因变成unassigned状态的索引。Allocator对主分片只允许分配在有最完整数据的节点上,对于副本分片则需要找到某个节点本地是否已经有改数据的副本,优先分配到该节点上。AllocationDecider处理逻辑相同。
Allocator构成

PrimaryShardAllocator 用于寻找拥有最新数据的主分片
ReplicaShardAllocator 用于寻找拥有某个副本分片的节点
BalancedShardsAllocator 通过节点分片负载均衡权重算法对数据节点按权重逆序排列
计算节点权重的方法如下:

该算法由两个权重参数控制:cluster.routing.allocation.balance.index,cluster.routing.allocation.balance.shard。他们分别乘节点分片数减去集群平均节点分片数,以及某索引节点分片数减某分片集群平均节点分片数。用此权重值代表集群分片均衡程度,显然此值越大代表分片在该节点越集中,越小代表节点分片压力越小,会排在待分配节点列表更前面。
AllocationDecider
所有Decider都实现了抽象类AllocationDecider,并重写了canRebalance,canAllocate,canRemain,canForceAllocatePrimary等方法。

下面分别介绍每类决策器作用以及控制参数
1、负载均衡类
SameShardAllocationDecider
功能:避免副本分片分配到同一个节点;一般多实例时使用。
参数:
参数名称 | 解释 |
|---|---|
cluster.routing.allocation.same_shard.host | 多实例情况下应该设置为true避免同一索引主副本分配到同一服务器,默认值为false。 |
ShardsLimitAllocationDecider
功能:节点上允许分配某个索引的分片数量。
参数:
参数名称 | 作用 |
|---|---|
index.routing.allocation.total_shards_per_node | 每个节点上最多允许分配某一索引分片数量;默认值是-1,表示无限制。 |
cluster.routing.allocation.total_shards_per_node | 每个节点上最多允许分配分片数量;默认值是-1,表示无限制。上面配置会覆盖此配置值。 |
AwarenessAllocationDecider
功能:让分片在不同机架间均衡分布。
参数:
参数名称 | 作用 |
|---|---|
cluster.routing.allocation.awareness.attributes | 配合自定义节点属性使用,让分片在不同机架间均衡分布。 |
cluster.routing.allocation.awareness.force. | 配合自定义节点属性使用,让分片强制分配在某些机架。 |
使用方式参照:
2、并发控制
ConcurrentRebalanceAllocationDecider
功能:rebalance操作的并发控制。
参数:
参数名称 | 作用 |
|---|---|
cluster.routing.allocation.cluster_concurrent_rebalance | 表示集群同时允许rebalance操作的分片数量,默认值是。 |
ThrottlingAllocationDecider
功能:见分片恢复阶段限速配置,避免同时太多分片恢复造成节点负载过高的情况。
参数:
参数名称 | 作用 |
|---|---|
cluster.routing.allocation.node_initial_primaries_recoveries | 限制当前节点主分片恢复数量,默认值是4。 |
cluster.routing.allocation.node_concurrent_incoming_recoveries | 限制其他节点上副本恢复到该节点的数量,默认值是2。 |
cluster.routing.allocation.node_concurrent_incoming_recoveries | 限制当前节点副本恢复到其他节点的数量,默认值是2。 |
cluster.routing.allocation.node_concurrent_recoveries | 限制当前节点分片恢复的数量,会覆盖上面两个参数。 |
3、条件限制
DiskThresholdDecider
功能:检查节点上磁盘空间是否超过设置水位线。
参数:
参数名称 | 作用 |
|---|---|
cluster.routing.allocation.disk.threshold_enabled | 是否开启磁盘水位线检测,默认值是true。 |
cluster.routing.allocation.disk.watermark.low | 达到此值后,新建索引分片不会往节点上分配,默认值是85%。 |
cluster.routing.allocation.disk.watermark.high | 达到此值后,该节点上的分片会rebalance到其他节点,默认值是90% |
RebalanceOnlyWhenActiveAllocationDecider
功能:所有分片都处于active状态才执行Rebalance操作
参数:无
ReplicaAfterPrimaryActiveAllocationDecider
功能:保证只有主分片分配完后才分配副本
参数:无
FilterAllocationDecider
功能:通过restAPI 动态设置的分片分配过滤器,可以指定分片往某些节点分配或者限制分片往某些节点分配,cluster级别配置会覆盖index级别参数。
参数:
注:以下配置中{attribute}可以是_name,_ip,_host。
参数名称 | 作用 |
|---|---|
cluster.routing.allocation.require.{attribute} | 分片必须往某节点上分配。 |
cluster.routing.allocation.include.{attribute} | 分片可以往某节点上分配 |
cluster.routing.allocation.exclude.{attribute} | 分片不允许往某节点上分配 |
index.routing.allocation.require.{attribute} | 分片必须往某节点上分配。 |
index.routing.allocation.include.{attribute} | 分片可以往某节点上分配 |
index.routing.allocation.exclude.{attribute} | 分片不允许往某节点上分配 |
ClusterRebalanceAllocationDecider
功能:判断分片是否可以执行rebalance操作。
参数:
参数名称 | 作用 |
|---|---|
cluster.routing.allocation.allow_rebalance | always:任何情况下都允许rebalance indices_primaries_active:所有主朱分片都分配完才能执行rebalance indices_all_active(默认值):所有分片都分配完才能执行rebalance |
MaxRetryAllocationDecider
功能:限制分片分配失败次数。
参数:
参数名称 | 作用 |
|---|---|
index.allocation.max_retries | 默认值是5。 |
4、其他决策
EnableAllocationDecider
功能:允许分片分配的类型,index级别配置会覆盖cluster级别配置。
参数:
参数名称 | 作用 |
|---|---|
cluster.routing.allocation.enable | all:允许所有类型分片 primaries:仅允许主分片 new_primaries:仅允许新建索引的主分片 none:禁止分片分配 |
index.routing.allocation.enable | 同上 |
cluster.routing.rebalance.enable | 同上 |
index.routing.rebalance.enable | 同上 |
NodeVersionAllocationDecider
功能:检查当前节点版本是否高于目标node版本,避免集群混部不同实例间版本不一致造成的Lucene结构不兼容。
参数:无
SnapshotInProgressAllocationDecider
功能:索引做快照期间是否允许分片分配。
参数:无
其他影响参数
索引恢复优先级
功能:分片级配置,数值越大越优先恢复。
配置方式:
在索引setting配置项中添加index.priority配置。默认按索引创建时间和索引名称排序,越新的索引越有可能排在前面。
延迟节点分配
功能:在主节点判断某一节点离开时,比如网络中断,节点重启或其他原因节点失去响应的情况下,集群会立刻在剩余的节点间rebalance,新建副本来替换离开节点的副本。为避免节点短时间离开造成的分片迁移,给处理节点离开留一些时间,可以配置节点延迟分配。
配置方式:
PUT _all/s_settings
{
"settings": {
"index.unassigned.node_left.delayed_timeout": "5m"
}
}由上面一系列分析可知,elasticsearch分片均衡机制和权重算法都依赖于分片数量,用分片数量简单代替了集群负载,这样假设的前提是每个分片上磁盘占用、IO负载、内存占用以及CPU使用是相同的。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。