天天看点

记一次线上环境 ES 主分片为分配故障

elasticsearch 版本:5.2

集群节点数:5

索引主分片数:5

索引分片副本数:1

线上环境es存储的数据量很大,当天由于存储故障,导致一时间 5个节点的 es 集群,同时有两个节点离线,一个节点磁盘只读(机房小哥不会处理,无奈只有清空数据重新安装系统),一个节点重启后,es集群报个别索引分片分配异常,es索引出于保证数据一致性的考虑,并没有把重启节点上的副本分片提升为主分片,所以该索引处于个别主分片丢失 不可写入 状态(索引分片 red)。

记一次线上环境 ES 主分片为分配故障

由于此图是后来取消副本数为0后,截的图,所以此处并没有副本分片。

在网上找了找类似的处理方案,分为以下几个。

利用 <code>_reroute</code> api 进行分片路由。

pass: 分片都启不来,按照网上的操作执行失败。

利用 <code>_reindex</code> api 进行现有数据重新复制到新索引,然后把旧索引删除,新索引建立别名为老索引名称。

优点:因为如图分片 0 出于只读状态,所以数据是可以访问的,所以利用<code>_reindex</code>可以把副本分片的数据进行复制迁移到新索引,最大保证数据的安全性。

缺点:因为涉及的数据量比较大,而且<code>_reindex</code>效率很低,220g 的索引数据,大概要3-4天的时间才能写入完毕。线上环境等不了这么久。

也找了许多提升<code>_reindex</code>效率的方法,设置新索引的副本数为 0,禁用刷新 等等。提升效果都很小。

线上环境能够接受该索引部分数据的丢失,但求尽快恢复服务。

找了下官方文档,找到了如下方法。

利用 <code>_shard_stores</code> 接口,查看故障索引的分片异常原因。

(es5 节点上,我调用接口设置了副本数从1 变为 0,所以该只读索引还保存有原有分片 0 的副本分片节点信息,可忽略)

我们看到该索引的 0 主分片(故障主分片)以前是存在于 es3 节点上的。es 由于数据安全性保证,在两个节点都有离线的情况下,锁住了 0 主分片的写入,导致索引也出于只读状态。

我们可以手动调用集群的 <code>reroute</code> 接口,在接受部分数据丢失的情况下,我们可以把 es3 节点上的原有副本,强制提升为索引的主分片。

官方文档 说明。

此外,<code>/_cluster/reroute</code> 接口还能够接受手动分配一个空的主分片到已有索引分配之中。谨慎使用

这种更残暴,直接把分片数据清空,强制拉上线。 但是这也不失为一种处理方法。

最终,该索引恢复正常。

记一次线上环境 ES 主分片为分配故障

继续阅读