聊一聊Elasticsearch的索引的分片分配机制
1、什么是分片分配
分片分配是由ES主节点将索引分片移动到ES集群中各个节点上的过程。
该过程尽量保证,同一个索引的分片尽量分配到更多的节点上,以此来达到读写索引的时候可以利用更多硬件资源的效果。
在分配过程当中,也不能将某个主分片和它的副本分片分配到同一个节点上,或者将某个主分片的多个副本分片分配到同一个节点上。之所以这样是因为怕某个节点挂掉了会导致整个集群丢失数据。这里引申出以下一个问题:
如果某索引的副本分片数量大于集群中的节点数量,那多出来的副本分片会如何呢?
答案是:多出来的副本分片将无法得到分配,在集群中也将无法发挥任何作用。
2、分片分配的过程
本节将通过一个ES集群中节点数量的变化,来看下分片的分配情况。
- 场景一:假设在一个单节点的ES集群中,创建一个索引,该索引有3个主分片,每个主分片有一个副本分片。
如上图:由于ES集群中只有一个节点(节点-0),所以索引的三个主分片(主分片-0、主分片-1、主分片-2)都被分配到了该节点上,而与这三个主分片对应的三个副本分片,则由于集群中无其他节点,使得它们没有得到分配。 - 场景二: 基于【场景一】我们在ES集群中再加一个新的节点(节点-1),此时ES集群中有2个节点,分别为:节点-0、节点-1。
如上图:与3个主分片对应的副本分片(副本分片-0、副本分片-1、副本分片-2、)被分配到了新的节点(节点-1)上。 - 场景三: 还是基于【场景一】我们把S集群中有的节点增加为3个,分别为:节点-0、节点-1、节点-2。
如上图:ES集群中每个节点上都有两个分片(达到了分片平衡),并且任一节点挂掉都不会导致数据的丢失。 - 场景四:试想如果节点的数量超过了分片的数量,即将【场景一】中的集群扩充到7个节点或者更多。
如上图:当ES集群中的节点数N达到了总分片数,继续增加节点的数量也无法提升该索引的读写性能(新增的节点上无可分配的索引分片,所以也就无法提供写服务和读服务了)。
3、分片分配的感知
基于上边介绍的【场景三】为例,我们再增加一个场景条件:「节点-0」和「节点-1」是分属于同在一台物理服务器(服务器A)上的两个不同虚拟机(虚拟机-0和虚拟机-1),而「节点-2」是另外一台物理服务器(服务器B)上的虚拟机(虚拟机-2),如下图所示:
我们来设想下如果「服务器A」挂掉了会怎么样?由于「主分片-0」和它的副本分片「副本分片-0」都在服务器A上,所以「服务器A」挂掉后会导致「主分片-0」上的数据丢失。
为了要解决这个问题,我们可以使用分片分配的感知,来人为对副本分片分配的位置进行干预。将ES集群中的节点进行区域划分,不允许副本分片被分配到它的主分片所属的区域内。
使用分片分配感知后的结果如下图:
如上图:我们可以看到在同一个区域内,不允许主分片和它的副本分片同时存在,这样的话即使「节点-0」和「节点-1」都挂掉了,也不会出现数据丢失的问题。
4、分片分配的过滤
所谓的分片分配的过滤指的是:我们可以通过配置来指定分片分配的时候只能分配到某些节点上或不能分配到某些节点上。
当我们要从ES集群中删除某个节点的时候,在该节点被删除前,我可以使用分片分配过滤将该节点上的所有分片分配到其他节点上。
使用该功能有一个前提条件:为每一个节点设置一些属性,以便于设置过滤条件的时候将节点区分开来。例如,在某个节点的elasticsearch.yml中自定义一个state属性,如下:
node.attr.state: vip
5、参考文献
- 《Elasticsearch数据搜索与分析实战》——王深湛
上一篇:《聊一聊Elasticsearch的基本原理与形成机制》