具体的restoreSnapshot方法
好的,让我们详细分析 restoreSnapshot
方法。这个方法位于 SnapshotServiceImpl
类中,负责从快照中恢复指定的索引。以下是方法的详细分析:
方法签名
private void restoreSnapshot(String repositoryName, String snapshotName, List<String> indicesList, Date delTime, Long id) throws IOException {
- 参数:
repositoryName
:快照仓库的名称。snapshotName
:快照的名称。indicesList
:需要恢复的索引列表。delTime
:删除时间。id
:记录的 ID,用于数据库操作。
- 异常:
IOException
:如果在恢复过程中发生 I/O 错误,则抛出此异常。
方法逻辑
-
查询快照信息:
List<SnapshotInfo> snapshotInfoList = queryIndicesByRepoAndSnapshot(repositoryName, snapshotName);
- 调用
queryIndicesByRepoAndSnapshot
方法查询指定仓库和快照的信息。
- 调用
-
过滤索引列表:
if (!snapshotInfoList.isEmpty() && !snapshotInfoList.get(0).indices().isEmpty()) { List<String> snapshotIndicesList = snapshotInfoList.get(0).indices(); indicesList = indicesList.stream().filter(snapshotInfo -> snapshotIndicesList.contains(snapshotInfo)).collect(Collectors.toList()); }
- 如果查询结果不为空且包含索引信息,则过滤
indicesList
,只保留存在于快照中的索引。
- 如果查询结果不为空且包含索引信息,则过滤
-
检查索引是否存在:
if (!indicesList.isEmpty()) { List<String> notExistsIndicesList = indicesList.stream().filter(index -> !elasticSearchService.isIndexExist(index)).collect(Collectors.toList());
- 进一步过滤
indicesList
,只保留那些在 Elasticsearch 中不存在的索引。
- 进一步过滤
-
记录恢复请求:
if (id == 0 && !notExistsIndicesList.isEmpty()) { IndicesRestoreRecord record = new IndicesRestoreRecord(); record.setRepositoryName(repositoryName); record.setSnapshotName(snapshotName); record.setIndicesName(JSON.toJSONString(notExistsIndicesList)); record.setIsSuccess(false); record.setDelTime(delTime); indicesRestoreRecordMapper.insert(record); }
- 如果
id
为 0 且存在需要恢复的索引,则创建一个IndicesRestoreRecord
记录,并将其插入数据库。
- 如果
-
准备恢复对象:
for (String indices : notExistsIndicesList) { IndicesRestore restore = new IndicesRestore(); restore.setId(null); restore.setDelFlag(0); restore.setDelTime(delTime); restore.setRestoredIndexName(indices + "_restored_" + LocalDate.now()); restore.setRestoredTime(new Date()); indicesRestores.add(restore); }
- 为每个需要恢复的索引创建一个
IndicesRestore
对象,并添加到indicesRestores
列表中。
- 为每个需要恢复的索引创建一个
-
构建恢复请求:
if (CollectionUtils.isNotEmpty(notExistsIndicesList)) { RestoreSnapshotRequest request = new RestoreSnapshotRequest(repositoryName, snapshotName); request.indices(notExistsIndicesList); log.info("索引:{}, 开始恢复。", notExistsIndicesList); Map<String, Object> map = Maps.newHashMap(); map.put("index.lifecycle.name", null); request.indexSettings(map); request.renamePattern("(.+)"); request.renameReplacement("$1_restored_" + LocalDate.now()); request.waitForCompletion(true);
- 构建
RestoreSnapshotRequest
对象,设置需要恢复的索引列表和其他配置。 - 设置索引生命周期名称为
null
,以便恢复后索引不再受生命周期管理。 - 设置重命名模式和替换规则,以便恢复的索引名称带有
_restored_
前缀。 - 设置
waitForCompletion
为true
,表示等待恢复操作完成。
- 构建
-
异步监听恢复结果:
ActionListener<RestoreSnapshotResponse> listener = new ActionListener<RestoreSnapshotResponse>() { @Override public void onResponse(RestoreSnapshotResponse restoreSnapshotResponse) { log.info("快照恢复onResponse返回 {}", indicesRestores); for (IndicesRestore restore : indicesRestores) { indicesRestoreMapper.insert(restore); } // 更新回复成功记录 String indicesName = JSON.toJSONString(notExistsIndicesList); Example example = new Example(IndicesRestoreRecord.class); example.createCriteria().andEqualTo("indicesName", indicesName); IndicesRestoreRecord indicesRestoreRecord = new IndicesRestoreRecord(); indicesRestoreRecord.setIsSuccess(true); indicesRestoreRecordMapper.updateByExampleSelective(indicesRestoreRecord, example); log.info("快照恢复成功, [indicesList:{}]", indicesRestores); } @Override public void onFailure(Exception e) { AtomicBoolean flag = new AtomicBoolean(true); log.info("onFailure进入, 开始校验快照恢复索引是否存在。"); indicesRestores.forEach(indicesRestore -> { log.info("校验索引{}, 是否存在。", indicesRestore.getRestoredIndexName()); if (!elasticSearchService.isIndexExist(indicesRestore.getRestoredIndexName())) { log.info("快照恢复, 索引:{}, 恢复失败。", indicesRestore.getRestoredIndexName()); flag.set(false); } }); log.info("最终恢复结果:{}", flag.get()); if (flag.get()) { for (IndicesRestore restore : indicesRestores) { indicesRestoreMapper.insert(restore); } // 更新回复成功记录 String indicesName = JSON.toJSONString(notExistsIndicesList); Example example = new Example(IndicesRestoreRecord.class); example.createCriteria().andEqualTo("indicesName", indicesName); IndicesRestoreRecord indicesRestoreRecord = new IndicesRestoreRecord(); indicesRestoreRecord.setIsSuccess(true); indicesRestoreRecordMapper.updateByExampleSelective(indicesRestoreRecord, example); log.info("快照恢复成功, [indicesList:{}]", indicesRestores); } } }; restHighLevelClient.snapshot().restore(request, RequestOptions.DEFAULT, listener);
- 创建一个
ActionListener
监听恢复操作的结果。 - 在
onResponse
方法中,记录恢复成功的索引,并更新数据库中的记录。 - 在
onFailure
方法中,校验恢复的索引是否存在,如果所有索引都恢复成功,则更新数据库中的记录。
- 创建一个
总结
restoreSnapshot
方法的主要功能是从快照中恢复指定的索引,并记录恢复过程中的各种状态。具体步骤包括:
- 查询快照信息。
- 过滤需要恢复的索引。
- 记录恢复请求。
- 准备恢复对象。
- 构建恢复请求。
- 异步监听恢复结果,并更新数据库记录。
这个方法通过详细的步骤和异常处理,确保了快照恢复操作的可靠性和可追溯性。