ES数据迁移与集群容灾

467 阅读3分钟

数据迁移

可接受停止读写的场景:
elasticsearch-dump、logstash、reindex、snapshot等方式进行数据迁移。

  • scroll query + bulk: 批量读取旧集群的数据然后再批量写入新集群,elasticsearch-dump、logstash、reindex都是采用这种方式
  • snapshot: 直接把旧集群的底层的文件进行备份,在新的集群中恢复出来,相比较scroll query + bulk的方式,snapshot的方式迁移速度最快。

不可接受停止读写的场景:

  • 如果业务不是直接写ES, 而是把数据写入到了中间件,比如业务->kafka->logstash->es的架构,此时可以直接采用双写的策略,旧集群不停止读写,新的集群也直接写入,然后迁移旧集群的数据到新集群中去,等数据追平之后,新的集群再提供读服务;
  • 如果业务是直接写ES, 并且会进行删除doc操作;此时可以使用ES官方在6.5版本之后的CCR(跨集群复制)功能,把旧集群作为Leader, 新集群作为Follower, 旧集群不停止读写,新集群从旧集群中follow新写入的数据;另一方面使用第三方工具把存量的旧集群中的数据迁移到新集群中,存量数据迁移完毕后,业务再切换到新的集群进行读写。

其他:
logstash:支持从一个ES集群中读取数据然后写入到另一个ES集群,因此可以使用logstash进行数据迁移.

input { elasticsearch { hosts => ["http://x.x.x.1:9200"] index => "*" docinfo => true } } output { elasticsearch { hosts => ["http://x.x.x.2:9200"] index => "%{[@metadata][_index]}" } }

reindex

reindex:Elasticsearch提供的一个api接口,可以把数据从一个集群迁移到另外一个集群。
snapshot: cloud.tencent.com/developer/a…

集群容灾

同城跨机房容灾:主备集群

image.png 一般有两种方式
第一种:双写,业务侧保证,比较复杂; 第二种:数据异步复制,数据一致性很难保证。
第三种:专线打通,实现跨机房部署,成本很高。

同城跨机房容灾:跨机房部署集群

image.png

如果两个可用区内分别存在一个专用主节点,可能会产生脑裂问题,可解决:
在两个可用区呢,分别存在两个、一个专用主节点,可避免脑裂的情况。

image.png 如果可用区2挂掉了,就无法进行选主了,因为投票数肯定会小于2,可解决:
这样就只能进行故障恢复和重建节点了: 先将投票阈值设置为1,等到挂掉的两个节点恢复之后,再将阈值设置为2,以避免脑裂情况的发生。

那可以同时把脑裂和无法选主的问题解决了吗
国内某云厂商的解决思路:

image.png 创建集群时,必须创建3个或5个专用主节点,后台会在一个隐藏的可用区内只部署专用主节点:
可以支持一个分区挂掉的选主,也可以避免脑裂。

异地容灾:主备集群

可以进行异步同步,但是实现会很复杂,且延时会很高,很容易出现时数据不一致的情况。
那么可以这样:
使用snapshot备份功能,定期比如每个小时在主集群中执行一次备份,然后在备集群中进行恢复,但是主备集群会有一个小时的数据延迟。

image.png

image.png

CCR是类似于数据订阅的方式,主集群为Leader, 备集群为Followe, 备集群以pull的方式从主集群拉取数据和写请求;
CCR的优点当然是因为可以同步UPDATE/DELETE操作,数据一致性问题解决了,同步延时也减小了。