关闭数据平衡
当我们试图关闭一个节点时,ES会立即试图复制这个节点中的数据到集群中其他节点上,这个过程会造成大量的IO请求,在关闭该节点的时候可以通过设置一下参数来避免此问题的发生:
curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d'
{
"persistent": {
"cluster.routing.allocation.enable": "none"
}
}
transient
与persistent
的区别见:这里
仅仅做这一步还是不够的,即使数据没有发生变化,仍然会出现大量主副分片之间的数据拷贝。原因是在于recovery是简单的对比主副分片的segment file(分段文件)来判断哪些数据一致是可以本地恢复,哪些不一致的需要重新拷贝的。而不同节点的segment file是完全独立运行的,这可能导致主副本merge的深度不完全一致,从而造成及时文档集完全一样,而产生的segment file却不完全一样。
因此通过synced flush(同步刷新)为对应的shard加入一个synced flush id,这样在节点重启后,先对比主副shard的synced flush id,就可以知道两个shard是否完全相同,避免了不必要的segment file拷贝。
同步刷新
执行同步刷新,当停止一个索引时,分片的恢复会很快,所以要进行同步刷新请求:
POST _flush/synced
当有分片在集群重启过程中并没有发生更新,则跳过对这些分片的同步校验,提高分片恢复的速度。
原理是当没有索引操作时,id 标记会添加到分片上。标记可以作为一个快速的方式来检查两个分片的lucene索引一致是否一致;这种快速的id 比较主要用于 数据恢复或者重启后跳过第一个也是成本最高的阶段;这种情况下,segment 不需要copy,事务日志的重演会立即执行;当id 标记和flush 一起用的时候,事物日志很可能为空,更加加速了数据的恢复;
尽管很方便,但是有一些警告:
- 同步刷新是个尽最大努力的操作:任何正在执行索引的操作都会造成同步刷新失败;这就一位置有些分片可能刷新成功,而有些分片则刷新失败;
- 同步id 的标记在再次刷新是会移除掉;
这是因为刷新会替换低级别的储存标记的lucene 提交点;事物日志中未提交的操作不会移除id 标记;现实中,在任何时间,应该把索引操作视触发的移除标记为刷新一样;
note:有索引操作时,请求同步刷新是无害的;当索引空闲时同步刷新成功,否则失败;任何请求成功的同步刷新在数据恢复时更加迅速;
synced flush只对冷索引有效,对于热索引(5分钟内有更新的索引)无效,如果重启的节点包含有热索引,那还是免不了大量的拷贝。
关闭和升级所有节点
停止在集群中的所有节点上的服务。每一个节点都要进行单独升级。这个主要就是文件替换操作,注意保留日志记录。
启动集群
先启动master节点,然后在启动data节点。
等待集群变为yellow
当节点加入集群中后,它首先恢复存储在本地的主分片数据。最初的时候,通过_cat/health
请求发现集群的状态是红色,意味着不是所有的主分片都已分配。当每个节点主分片恢复完后,集群的状态将会变成yellow,这意味着所有主分片已经分配,而副本分片没有被分配。
分配副本分片
延迟副本的分配直到所有节点都加入集群,在集群的所有节点,可以重新启用副本分配:
curl -X PUT "localhost:9200/_cluster/settings" -H 'Content-Type: application/json' -d'
{
"persistent": {
"cluster.routing.allocation.enable": "all"
}
}
这个时候集群将开始复制所有副本到数据节点上,这样可以安全恢复索引和搜索,如果能延迟索引和搜索直到所有的分片已经恢复,这样可以加快集群的恢复。