shard recovery配置

shard recovery配置以及集群重启时的无意义shard重分配问题
notion image
在集群重启的时候,有一些配置会影响shard恢复的过程。首先,我们需要理解默认配置下,shard恢复过程会发生什么事情。如果我们有10个node,每个node都有一个shard,可能是primary shard或者replica shard,你有一个index,有5个primary shard,每个primary shard有一个replica shard。如果我们将整个集群关闭了进行一些维护性的操作,比如给机器安装新的磁盘之类的事情。当我们重启集群的时候,肯定节点是一个接一个的启动的,可能会出现5个节点先启动了,然后剩下5个节点还没启动。
也许是因为剩下的5个节点没来得及启动,或者是因为一些原因耽搁了,总之不管是什么原因,就是现在只有5个节点是在线的。这5个节点会通过gossip协议互相通信,选举出一个master,然后组成一个集群。他们会发现数据没有被均匀的分布,因为有5个节点没有启动,那么那5个节点上的shard就是不可用的,集群中就少了一半的shard。此时在线的5个node就会将部分replica shard提升为primary shard,同时为每个primary shard复制足够的replica shard。
最后,可能剩下的5个节点加入了集群。
但是这些节点发现本来是他们持有的shard已经被重新复制并且放在之前的5个node速度回当了,此时他们就会删除自己本地的数据。然后集群又会开始进行shard的rebalance操作,将最早启动的5个node上的shard均匀分布到后来启动的5个node上去。
在这个过程中,这些shard重新复制,移动,删除,再次移动的过程,会大量的耗费网络和磁盘资源。对于数据量庞大的集群来说,可能导致每次集群重启时,都有TB级别的数据无端移动,可能导致集群启动会耗费很长时间。
但是如果所有的节点都可以等待整个集群中的所有节点都完全上线之后,所有的数据都有了以后,再决定是否要复制和移动shard,情况就会好很多。
所以现在问题我们已经知道了,那么我们就可以配置一些设置来解决这个问题。首先我们需要设置一个参数,gateway.recover_after_nodes: 8。这个参数可以让es直到有足够的node都上线之后,再开始shard recovery的过程。
所以这个参数是跟具体的集群相关的,要根据我们的集群中节点的数量来决定。此外,还应该设置一个集群中至少要有多少个node,等待那些node的时间:gateway.expected_nodes: 10,gateway.recover_after_time: 5m。经过上面的配置之后,es集群的行为会变成下面这样,等待至少8个节点在线,然后等待最多5分钟,或者10个节点都在线,开始shard recovery的过程。
这样就可以避免少数node启动时,就立即开始shard recovery,消耗大量的网络和磁盘资源,甚至可以将shard recovery过程从数小时缩短为数分钟。