官方文档-分片分配和集群路由

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了官方文档-分片分配和集群路由相关的知识,希望对你有一定的参考价值。

参考技术A

对应7.2官方文档路径:Modules » Shard allocation and cluster-level routing
官方地址如下:
https://www.elastic.co/guide/en/elasticsearch/reference/7.2/modules-cluster.html

主节点的一个重要角色就是决定哪个分片分配到哪个节点,移动分片到不同节点目的是为了平衡集群。
以下设置可以控制分片分配过程:

集群级别分片分配: 一些控制分配和平衡的设置
基于磁盘的分片分配: 阐述es如何考虑可用磁盘空间以及相关设置
分片分配感知和强制感知: 控制分片如何在不同机架或者区域分配
集群级分片分配过滤: 允许某些节点或某些节点组从分配中排除,以便将其停用
除此以外,还有一些其他混杂的集群级别设置

这部分的设置都是动态设置,可以在活动的集群上使用用集群设置更新api动态更新。

分片分配是将分片分配到节点的过程,可能发生在初始化恢复,副本分配,重新平衡,节点的添加和移除的过程中。

以下动态设置可以用来控制分片分配和恢复:

启用或者禁用某些种类分片的分配:
all(默认): 允许全部种类分片分配
primaries: 只允许主分片分配
new_primaries: 允许新建的索引的主分片分配
none: 不允许任何分片分配

在一个node上允许同时恢复多少个shard,默认2

一个node上允许同时进行多少个shard recovery outgoing,比如这个node上,有一个primary shard,现在要将replica shard分配给其他的node,那么就是outgoing shard recovery。默认值也是2

同时设置上面两个值

在如果replica shard recovery通过网络传输来分配,那么一个未被分配的primary shard会在node重启之后使用本地磁盘上的数据,这个过程因为是使用本地的数据,因此会比较快,默认值是4

默认值是 false ,如果设置为true,那么就不允许将一个primary shard和replica shard分配到同一个物理机上,也许这个物理机上启动了多个es实例。

以下动态设置可用于控制整个群集中的分片重新平衡:

all(默认): 允许对所有类型的shard进行rebalance过程
primaries: 仅仅允许对primary shard进行rebalance过程
replicas: 仅仅允许对replica shard进行rebalance
none: 不允许对任何shard进行rebalance

always :任何时候都允许rebalance
indices_primaries_active: 仅在分配了集群中的所有主分片时,才能rebalance
indices_all_active(默认): 仅允许所有的主副分片都被分配之后,才能rebalance

允许控制多少个shard rebalance的操作同时运行,默认是2

//todo

默认85%不再分配分片,90%将移走分片,95%触发read_only

你可以使用自定义节点属性作为感知属性,以使es在分配分片时考虑你的物理硬件配置。如果es知道哪些节点在同一个物理服务器上,同一个机架或者同一个区域,他可以分发主/副分片到不同地方,以最大程度减少发生故障时丢失全部分片的风险。
当分片分配感知通过 cluster.routing.allocation.awareness.attributes 设置生效时,分片将仅分配给具有设置了特殊感知属性值的节点。如果设置了多个感知属性,es将分别考虑他们。
分配感知属性可以在yml文件中设置,或者通过cluster-update-settings api动态更新。
es倾向于在同一位置(相同感知属性值)的分片上进行search,get请求,使用本地shards将会比跨机架和区域边界更快。
注: 属性值的数量决定了每个位置分配了多少个分片副本。如果每个位置中的节点数量不平衡,并且有很多副本,则副本分片可能未分配。

你也可以在启动节点的时候设置自定义属性:

注:多个属性以逗号分割填写
你也可以通过 cluster-update-settings api 设置或者更新集群感知属性。

使用以上例子的配置,如果你启动两个 node.attr.rack_id rack_one 的节点,并创建一个5个主分片一个副本的索引,则全部的主分片和副本将分配到这两个节点。
如果你再添加两个 node.attr.rack_id rack_two 的节点,es将移动分片到新的节点。来保证没有分片和其副本在同一个rack里面(如果可以做到的话)。
当rack_two的节点都挂掉,默认es将分配丢失的分片副本到rack_one。为了避免某一特定分片的副本分配到相同的区域,你可以使用强制感知。

默认的,如果一个区域失败了,es将分配所有丢失的副本到尚存的区域。也许你拥有充足的跨区域资源来持有你的全部主分片和副本分片,但是一个区域也许不能持有全部的分片。
为了避免发生故障时某一个区域过载,你可以设置cluster.routing.allocation.awareness.force,这样直到其他的区域可用才会分配副本。
例如,你有一个感知属性zone,配置了节点分别为zone1,zone2,你可以用强制感知来避免es在只有一个zone区域可用时分配副本。

为感知属性指定所有可能的值:
通过以上的例子,当你启动两个node.attr.zone为zone1的节点,并创建一个5分片1副本的索引,es将创建索引并分配5个主分片,但是副本不会分配,除非有一个node.attr.zone为zone2的节点可用。

你可以使用集群级别分片分配过滤控制es将任何索引的分片分配到哪里,这个集群级别的过滤可以和每个索引分配过滤和分配感知配合使用。
分片分配过滤可以基于自定义节点属性或者内置的属性_name,_ip或者_host。
cluster.routing.allocation设置是动态的,允许将活动的索引从一组节点移动到另一组节点。分片只有在不打破其他路由规则的前提条件下才可以移动,例如不能将主副分片移动到同一个节点。
最常用的集群级别分片分配过滤就是当你想下线一个节点的时候,将分片从此节点一走后停止这个节点,可以使用如下api通过ip过滤此节点:

cluster.routing.allocation.include.attribute
将分片分配给attribute属性至少匹配一个逗号分隔中的值的节点。
cluster.routing.allocation.require.attribute
仅将分片分配给attribute属性具有所有逗号分隔后的值的节点。
cluster.routing.allocation.exclude.attribute
禁止将分片分配给attribute属性具有任何一个逗号分隔后的值的节点。

_name : 通过节点名字匹配
_ip : 通过ip地址匹配(与hostname相关联的ip)
_host : 通过hostname匹配
你可以使用通配符描述属性值,例如:

cluster.blocks.read_only
将整个群集设为只读(索引不接受写操作),不允许修改元数据(创建或删除索引)。
cluster.blocks.read_only_allow_delete
与cluster.blocks.read_only索引相同,但允许删除索引以释放资源
cluster.max_shards_per_node
控制每个数据节点在集群中允许的分片数量
……

MogoDB 分片键

MongoDB 根据分片键分割 collection 中的文档,然后分配到分片集群的成员中。

分片键可以是一个存在于每个文件中的索引字段或者复合索引字段。

MongoDB 使用不同范围的分片键值来分割 collection 中的数据。不同分片键范围是不重叠的并且每个分片键范围与一个 chunk 关联。

选择分片键

选择的分片键要尽量使 chunks 平滑的分配到集群的分片中。如果不那么做,会影响集群的性能:

  • 假设所有的 chunks 都被分配到一个 分片中,那么整个集群的能力就是这一台分片的能力
  • 假设 chunks 没有均匀分配,集中在一个分片中,那么这个分片可能会成为瓶颈。因为总的耗时取决于最慢的那个分片

为了选择出好的分片键,还需要了解分片键的以下性质

  • 基数性
  • 频率
  • 单调改变

基数性

分片键的基数性决定了平衡器可以创建的最大 chunks 数目。

在任意时刻,一个唯一的键值对只能存在于不超过一个的 chunk 中。现有一个基数性为 4 的分片键,那么在集群中最多有 4 个(有效的) chunks,因为增加额外的分片不会带来收益,每个 chunk 储存一个唯一的分片键。

然而高的基数性也不能保证数据在集群中平滑分配,这还与频率和单调性有关。当选择分片键时,这三个因素都要考虑到。

频率

分片键的频率指给定的分片键值在文件中多常出现。

如果大部分的文件只包含一部分分片键,那么储存大部分文件的分片会成为集群的瓶颈。如果大部分文件只包含一个分片键,那么对应的 chunk 会很大并且不可分割。这就会降低集群的性能。

如果你的数据模型需要在一个高频率的分片键,考虑使用一个唯一的或者低频率的复合索引代替。

单调改变的分片键

单调改变指分片键是单调递增或单调递减的,这样的分片键更容易插入到集群中的一个分片中(而不是均匀分配)。

发生这种情况的原因是每个集群都有两个 chunk 捕捉超出边界的分片键。一个捕捉超出(分片键的)最大值的分片键,一个捕捉小于最小值的分片键。

如果一个分片键是单调递增的,那么在一定时刻之后,所有新增都会进入到 [maxKey, 正无穷] 这个 chunk。同理,单调递减的分片键会进入 [负无穷, minKey]。包含对应 chunk 的分片就会成为写操作的瓶颈。

唯一索引

只有使用整个分片键作为其前缀的唯一索引才能确保其是跨分片唯一的[2]。

哈希分片

哈希分片使用一个字段的哈希索引作为分片键来分割数据。

哈希分片以牺牲查询隔离性为代价来提供分布更加均匀的分片集群。分片值相邻的文档更不可能在同样的分片上,因此对应给定的范围查询 mongos 更可能去执行广播查询。同时,mongos 也能匹配相等的查询到一个分片上。

哈希分片键

选择作为哈希分片键的字段应该有高基数性。假设没有高基数性,那么数据就会集中到某些分片上而不是均匀分配到所有分片,然后数据过多的分片会造成瓶颈。

理想的哈希分片键是单调性的字段,比如 ObjectId 或者时间。

分片键的限制

大小

分片键的大小不能超过 512 bytes。

分片键索引类型

分片键的索引可以是在分片键上递增的索引,一个以分片键为前缀的在分片键上递增的复合索引或是一个哈希索引。

分片键索引不能是在分片键字段上的多键索引、文本索引或者地理空间索引。

分片键不可改变

如果你一定要改变分片键:

  • 导出所有数据
  • Drop 旧的分片 collection
  • 设置新的分片键
  • 预先分割分片键的范围来确保初始分配是均匀的
  • 导入数据

文档中的分片键不可改变

你不能修改分片键在文本中的对应字段的值。

参考

  1. https://docs.mongodb.com/manual/core/sharding-shard-key/#shard-key
  2. https://docs.mongodb.com/manual/reference/limits/#sharded-clusters

以上是关于官方文档-分片分配和集群路由的主要内容,如果未能解决你的问题,请参考以下文章

Es官方文档整理-2.分片内部原理

Elasticsearch6.4集群报yellow和red状态问题

mongo 分片集群的搭建

maxscale跨库分片的限制

maxscale跨库分片的限制

[译文]还原MongoDB 分片集群到另一个环境