ElasticSearch 8.x 使用 snapshot(快照)进行数据迁移

ElasticSearch

1、ElasticSearch学习随笔之基础介绍
2、ElasticSearch学习随笔之简单操作
3、ElasticSearch学习随笔之java api 操作
4、ElasticSearch学习随笔之SpringBoot Starter 操作
5、ElasticSearch学习随笔之嵌套操作
6、ElasticSearch学习随笔之分词算法
7、ElasticSearch学习随笔之高级检索
8、ELK技术栈介绍
9、Logstash部署与使用
10、ElasticSearch 7.x 版本使用 BulkProcessor 实现批量添加数据
11、ElasticSearch 8.x 弃用了 High Level REST Client,移除了 Java Transport Client,推荐使用 Elasticsearch Java API
12、ElasticSearch 8.x 使用 snapshot(快照)进行数据迁移
13、ElasticSearch 8.x 版本如何使用 SearchRequestBuilder 检索

ElasticSearch,创始人 Shay Banon(谢巴农)
本文主要讲解ElasticSearch 数据快速迁移。


文章目录

  • ElasticSearch
  • 前言
  • 一、什么是ES的快照
  • 二、快照生成
    • 2.1 新建仓库
      • 2.1.1 Kibana操作
      • 2.1.2 JAVA API操作
        • 2.1.2.1 引入 pom 依赖
        • 2.1.2.2 初始化客户端
        • 2.1.2.3 创建仓库(参数方式)
        • 2.1.2.3 创建仓库(配置文件方式)
    • 2.2 生成快照
      • 2.2.1 Kibana操作
      • 2.2.2 JAVA API操作
    • 2.3 删除快照
      • 2.3.1 Kibana操作
      • 2.3.2 JAVA API操作
  • 三、恢复快照
    • 3.1 Kibana操作
    • 3.2 JAVA API操作


前言

平时在工作中,很多时候都是需要搭建好几个测试平台来保证应用的运行是否流畅,有没有 Bug,数据是否正确,一般都是 dev、pre 等测试环境,通过一系列的测试之后没有什么问题,才会把 应用 和 数据 部署到 prod 环境,应用一般都是大包 prod 环境的部署包,直接部署,而数据则就需要很长的实际来同步了,如果是一些统计咨询类的企业应用,那数据上线就有可能花费掉大量的时间了。
此篇就来浅谈一下,项目中应用到了 ElasticSearch 来做数据检索,那在项目上线的时候,我们如何快速的把大量数据快速从一个 ElasticSearch索引迁移到另一个索引库。
快照和恢复
A snapshot is a backup of a running Elasticsearch cluster.
官网上说,一个快照就是一个备份在 Elasticsearch 集群上运行的时候,快照可以用于以下几点:

  • 集群服务不停的情况下定期备份数据;
  • 删除或者硬件出错后恢复数据;
  • 在两台集群中间传输数据;
  • 通过在冷和冻结数据层中使用可搜索的快照来降低存储成本;

那具体什么是快照呢?

一、什么是ES的快照

Elasticsearch 的快照就是指对数据和元数据的定期备份。因为快照中不仅包含了所有数据,也包含了所有的相关信息,比如:映射、配置等;这些快照可以保存在本地文件系统,也可以保存在共享文件系统或者专门存储快照的地方。

在快照的概念中,数据并不都是每次全部备份一遍,而是采用增量的方式进行进行备份。首次备份会进行全力备份,而后续的备份则是在上一次备份后的更新的数据,增量备份可以有效地减少备份所需的存储空间和节省时间。

对于 Elasticsearch 的迁移,快照和恢复则是很常用的一种强大的方式,在源集群上创建索引的快照,拷贝到其他集群后在恢复,也可以用 API 的方式来进行快照和恢复,这里就用 JAVA + Elasticsearch Client 实现,这样在我们后台应用就可以完成数据迁移了。

二、快照生成

2.1 新建仓库

2.1.1 Kibana操作

可以通过 Kibana 指令来注册快照,命令如下:

POST _snapshot/productInfo
{"type": "fs","settings": {"location": "/data/esbackup/product_info"}
}

执行以上指令,有可能报错,一般会报如下错误:

"caused_by": {"type": "repository_exception","reason": "[productInfo] location [/data/esbackup] doesn't match any of the locations specified by path.repo because this setting is empty"
}

报上述错误一般是 Elasticsearch 服务没有配置 path.repo 这个参数,只需要在 elasticsearch.yml 中配置 path.repo: /data/repository 即可。

如果报错如下:

"caused_by": {"type": "access_denied_exception","reason": "/data/repository/tests-gU8mf7EvREG_1qMc3ZMApQ"
}

说明你配置的 path.repo 的路径没有访问权限,赋予权限即可:
chown -R elasticsearch:elasticsearch /data/esbackup/productInfo/

2.1.2 JAVA API操作

2.1.2.1 引入 pom 依赖
<dependency><groupId>org.elasticsearch.client</groupId><artifactId>elasticsearch-rest-high-level-client</artifactId><version>7.3.2</version>
</dependency>

注意: 再次感受到 elasticsearch-rest-high-level-client 对版本的严格区分,可能是我的 ElasticSearch 配置或者是其他原因,低版本的客户端使用 BulkProcessor 是没有问题的,但是在 获取快照 操作测报错,高版本的客户端在 获取快照时没问题,但是在 BulkProcessor 批量操作数据时报错,你的是否也有这个问题呢?

2.1.2.2 初始化客户端
/*** 通过认证连接ES,获取客户端*/
public static RestHighLevelClient createClient(){String hostname = "192.168.*.*";int port = 9200;String username = "your username";String password = "your password";final CredentialsProvider credentialsProvider = new BasicCredentialsProvider();credentialsProvider.setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(username, password));RestClientBuilder restClientBuilder = RestClient.builder(new HttpHost(hostname, port)).setHttpClientConfigCallback(httpAsyncClientBuilder -> httpAsyncClientBuilder.setDefaultCredentialsProvider(credentialsProvider));return new RestHighLevelClient(restClientBuilder);
}
2.1.2.3 创建仓库(参数方式)
/*** 创建仓库*/
public static void createRepository(RestHighLevelClient client, String repositoryName) {GetRepositoriesRequest getRepositoriesRequest = new GetRepositoriesRequest(new String[]{repositoryName});boolean hasRepository = false;try {GetRepositoriesResponse repository = client.snapshot().getRepository(getRepositoriesRequest, RequestOptions.DEFAULT);List<RepositoryMetadata> repositories = repository.repositories();for (RepositoryMetadata repositoryMetadata : repositories) {if(repositoryMetadata.name().equals(repositoryName)){hasRepository = true;break;}}} catch (ElasticsearchStatusException ee) {System.out.println("仓库不存在:" + ee.getMessage());} catch (IOException ioException) {// 客户端版本略低,所以用异常捕获方式判断,索引存在会抛到这里异常System.err.println(ioException.getMessage());hasRepository = true;}if(!hasRepository){try {PutRepositoryRequest repositoryRequest = new PutRepositoryRequest();repositoryRequest.name(repositoryName);repositoryRequest.verify(false);repositoryRequest.name(repositoryName);repositoryRequest.type("fs");repositoryRequest.settings(Settings.builder().put("location", "/data/esbackup/productInfo"));AcknowledgedResponse acknowledgedResponse = client.snapshot().createRepository(repositoryRequest, RequestOptions.DEFAULT);if (acknowledgedResponse.isAcknowledged()) {System.out.println("创建仓库成功: " + repositoryName);}} catch (IOException e) {e.printStackTrace();}}try {client.close();} catch (IOException e) {throw new RuntimeException(e);}
}
2.1.2.3 创建仓库(配置文件方式)
  • 配置文件如下:
    src/main/resources/productInfo.json
{"type": "fs","settings": {"location": "/data/esbackup/productInfo","compress": true}
}
  • 读取配置,创建仓库:
    注意:仓库名称 repositoryName 必须小写
/*** 创建仓库*/
public static void createRepository(RestHighLevelClient client, String settingPath, String repositoryName) {GetRepositoriesRequest getRepositoriesRequest = new GetRepositoriesRequest(new String[]{repositoryName});boolean hasRepository = false;try {GetRepositoriesResponse repository = client.snapshot().getRepository(getRepositoriesRequest, RequestOptions.DEFAULT);List<RepositoryMetadata> repositories = repository.repositories();for (RepositoryMetadata repositoryMetadata : repositories) {if(repositoryMetadata.name().equals(repositoryName)){hasRepository = true;break;}}} catch (ElasticsearchStatusException ee) {System.out.println("仓库不存在:" + ee.getMessage());} catch (IOException ioException) {// 客户端版本略低,所以用异常捕获方式判断,索引存在会抛到这里异常System.err.println(ioException.getMessage());hasRepository = true;}if(!hasRepository){try {String jsonString = new String(Files.readAllBytes(Paths.get(settingPath)), StandardCharsets.UTF_8);// 解析 jsonPutRepositoryRequest repositoryRequest = new PutRepositoryRequest();XContentParser contentParser = XContentFactory.xContent(XContentType.JSON).createParser(NamedXContentRegistry.EMPTY, DeprecationHandler.THROW_UNSUPPORTED_OPERATION, jsonString);repositoryRequest.name(repositoryName);repositoryRequest.verify(false);repositoryRequest.source(contentParser.map());AcknowledgedResponse acknowledgedResponse = client.snapshot().createRepository(repositoryRequest, RequestOptions.DEFAULT);if (acknowledgedResponse.isAcknowledged()) {System.out.println("创建仓库成功: " + repositoryName);}} catch (IOException e) {e.printStackTrace();}}try {client.close();} catch (IOException e) {throw new RuntimeException(e);}
}

2.2 生成快照

2.2.1 Kibana操作

POST _snapshot/product_info/product_info

2.2.2 JAVA API操作

注: 快照名称 snapshotName 必须小写

/*** 生成快照*/
public static boolean createSnapshot(RestHighLevelClient client, String snapshotName, String repositoryName, String... indexes) {CreateSnapshotRequest createSnapshotRequest = new CreateSnapshotRequest();createSnapshotRequest.indices(indexes);createSnapshotRequest.snapshot(snapshotName);createSnapshotRequest.repository(repositoryName);createSnapshotRequest.waitForCompletion(true);createSnapshotRequest.includeGlobalState(false);try {CreateSnapshotResponse snapshotResponse = client.snapshot().create(createSnapshotRequest, RequestOptions.DEFAULT);SnapshotInfo snapshotInfo = snapshotResponse.getSnapshotInfo();if (snapshotInfo.status().getStatus() == 200) {System.out.println("快照创建成功:" + snapshotInfo);return true;}} catch (IOException e){e.printStackTrace();} finally {try {client.close();} catch (IOException e) {throw new RuntimeException(e);}}return false;
}

快照生成成功,如图:
快照

2.3 删除快照

2.3.1 Kibana操作

DELETE _snapshot/product_info

2.3.2 JAVA API操作

/*** 删除快照*/
public static boolean deleteSnapshot(RestHighLevelClient client, String repositoryName) {DeleteSnapshotRequest deleteSnapshotRequest = new DeleteSnapshotRequest();deleteSnapshotRequest.snapshots(repositoryName);deleteSnapshotRequest.repository(repositoryName);try {AcknowledgedResponse deleteSnapshotResponse = client.snapshot().delete(deleteSnapshotRequest, RequestOptions.DEFAULT);if (deleteSnapshotResponse.isAcknowledged()) {System.out.println("快照删除成功!");return true;}} catch (IOException e) {e.printStackTrace();} finally {try {client.close();} catch (IOException e) {throw new RuntimeException(e);}}return false;
}

三、恢复快照

3.1 Kibana操作

POST _snapshot/product_info/product_info/_restore
{"indices": "product_info"
}

3.2 JAVA API操作

/*** 恢复快照*/public static void restoreSnapshot(RestHighLevelClient client, String snapshotName, String repositoryName, String indexes){RestoreSnapshotRequest restoreSnapshotRequest = new RestoreSnapshotRequest();restoreSnapshotRequest.snapshot(snapshotName);restoreSnapshotRequest.repository(repositoryName);restoreSnapshotRequest.indices(indexes);try {RestoreSnapshotResponse restoreSnapshotResponse = client.snapshot().restore(restoreSnapshotRequest, RequestOptions.DEFAULT);System.out.println("快照恢复成功:" + restoreSnapshotResponse.getRestoreInfo().toString());} catch (IOException e) {e.printStackTrace();} finally {try {client.close();} catch (IOException e) {throw new RuntimeException(e);}}}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/439310.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JavaSE——运算符、运算符优先级、API、Scanner

目录 基本的算术运算符 自增自减运算符 赋值运算符 关系运算符 逻辑运算符 三目运算符 运算符优先级 API Scanner 基本的算术运算符 符号作用加-减*乘/除%取余 基本与C语言的基本算术运算符一致 注意&#xff1a;两个整数相除结果还是整数 public static void main…

标准库中的string类(下)——“C++”

各位CSDN的uu们你们好呀&#xff0c;这段时间小雅兰的内容仍然是Cstring类的使用的内容&#xff0c;下面&#xff0c;让我们进入string类的世界吧&#xff01;&#xff01;&#xff01; string类的常用接口说明 string - C Reference string类的常用接口说明 string类对象的修…

一个基于 .NET 7 + Vue.js 的前后端分离的通用后台管理系统框架 - DncZeus

前言 今天给大家推荐一个基于.NET 7 Vue.js(iview-admin) 的前后端分离的通用后台权限(页面访问、操作按钮控制)管理系统框架&#xff1a;DncZeus。 官方项目简介 DncZeus是一个基于 .NET 7 Vue.js 的前后端分离的通用后台管理系统框架。后端使用.NET 7 Entity Framework…

Camunda组件与服务与基本操作

文章目录 下载与安装Camunda ModelerDownload Camunda 7 Run与Spring Boot集成普通Java项目中集成Camunda手动部署流程查询流程启动流程实例完成任务删除流程定义查找历史节点信息 下载与安装 Camunda下载 Camunda7下载 有2个组件需要下载&#xff1a; Open Source Desktop …

代码随想录算法刷题训练营day19

代码随想录算法刷题训练营day19&#xff1a;LeetCode(404)左叶子之和、LeetCode(112)路径总和、LeetCode(113)路径总和 II、LeetCode(105)从前序与中序遍历序列构造二叉树、LeetCode(106)从中序与后序遍历序列构造二叉树 LeetCode(404)左叶子之和 题目 代码 /*** Definitio…

JMeter GUI:测试计划和工作台

什么是测试计划&#xff1f; 测试计划是您添加 JMeter 测试所需元素的地方。 它存储运行所需测试所需的所有元素&#xff08;如线程组、计时器等&#xff09;及其相应的设置。 下图显示了测试计划的示例 测试计划是您添加 JMeter 测试所需元素的地方。 它存储运行所需测试…

自然语言nlp学习 三

4-8 Prompt-Learning--应用_哔哩哔哩_bilibili Prompt Learning&#xff08;提示学习&#xff09;是近年来在自然语言处理领域中&#xff0c;特别是在预训练-微调范式下的一个热门研究方向。它主要与大规模预训练模型如GPT系列、BERT等的应用密切相关。 在传统的微调过程中&a…

fgets函数和fputs函数的使用

----由于本人使用的是大白话来讲解fgets和fputs函数的使用&#xff0c;所以可能有些部分可能会有些不准确&#xff08;见谅&#xff09;&#xff0c;如果想十分严谨的了解fgets和fputs函数&#xff0c;可以移步其他文章。 -----那么不废话&#xff0c;直接开始 1.fgets函数 &a…

05. 交换机的基本配置

文章目录 一. 初识交换机1.1. 交换机的概述1.2. Ethernet_ll格式1.3. MAC分类1.4. 冲突域1.5. 广播域1.6. 交换机的原理1.7. 交换机的3种转发行为 二. 初识ARP2.1. ARP概述2.2. ARP报文格式2.3. ARP的分类2.4. 免费ARP的作用 三. 实验专题3.1. 实验1&#xff1a;交换机的基本原…

海外云手机为什么吸引用户?

近年来&#xff0c;随着全球化的飞速发展&#xff0c;海外云手机逐渐成为各行各业关注的焦点。那么&#xff0c;究竟是什么让海外云手机如此吸引用户呢&#xff1f;本文将深入探讨海外云手机的三大吸引力&#xff0c;揭示海外云手机的优势所在。 1. 高效的社交媒体运营 海外云…

IDEA安装MyBatisX插件

IDEA工具在开发人员中经常使用&#xff0c;从dao层到xml文件对应的查看很费劲&#xff0c;这时候就有相应的插件工具出现了MyBatisX。他的好处如下&#xff1a; mapper and xml can jump back and forth mybatis.xml,mapper.xml prompt mapper and xml support auto prompt lik…

MATLAB知识点:创建MATLAB的脚本

​讲解视频&#xff1a;可以在bilibili搜索《MATLAB教程新手入门篇——数学建模清风主讲》。​ MATLAB教程新手入门篇&#xff08;数学建模清风主讲&#xff0c;适合零基础同学观看&#xff09;_哔哩哔哩_bilibili 节选自第2章 在实际应用中&#xff0c;直接在命令行窗口中输…