一、前情提要
在项目中,大家很有可能遇到elasticsearch(以下简称ES)数据需要迁移的事件,比如从A集群迁移到B集群,A/B集群相互独立,在数据量大的时候,每时每刻都有数据刷新,那如何不停机平滑迁移呢,今天楼主有一种思路,不去采用运维迁移的方式,使用代码双写双读的方式来解决.
二、改动思路
迁移策略
- 在所有写入/更新索引的地方做双写,同时写入现有的公有集群索引和零担集群的索引 在所有查询索引的地方使
- 用开关切换查询老索引还是新索引,在读的地方加上数据对比
- 数据迁移调度job,数据比对的job
可能文字有点枯燥,上段双写的伪代码
// 以添加为例
@Service
public class EsIndexRepo {
@Autowired
@Qualifier("old")
ElasticsearchTemplate elasticsearchTemplate1;
@Autowired
@Qualifier("new")
ElasticsearchTemplate elasticsearchTemplate2;
//添加开关 这个地方可以统一配置
boolean oldSwitch;
//添加开关 这个地方可以统一配置
boolean newSwitch;
public void add(String...) {
if (oldSwitch) {
elasticsearchTemplate1.add(...);
}
if (newSwitch) {
elasticsearchTemplate2.add(...);
}
}
}
三:读写的流程图
四、执行步骤
- 选择在业务低峰期,先上线代码,不影响现有任何功能
- 迁移控制开关切换到双写状态,新老集群同时写新数据
- 线上观察异常,无异常继续下一步
- 逐个迁移ES到新集群,打开数据比对开关
- 迁移完成,逐个切换读开关到新集群
- 下线迁移代码