前几天,领导要求在现有系统上增加个数据(ES及MySqlDB)备份及还原功能,仔细想想DB备份常见,可直接java运行时执行mysqldump命令就行了,那么,Elasticsearch数据备份常见是使用curl工具执行指令,是不是也可以用java来代替操作呢?
不再犹豫--Beyond,直接开搞,在开搞之前,来复习有关ES操作的几个简单指令:
1、获取快照:curl -XPUT 'http://ip:port/_snapshot/reponame',reponame仓库快照名称,可用于判断仓库快照是否存在;
2、创建仓库快照 :curl -XPUT 'http://ip:port/_snapshot/reponame'
3、创建快照(备份):curl -XPUT 'http://ip:port/_snapshot/reponame/snapshot_name1?wait_for_completion=true' ,wait_for_completion=true 表示等待创建完成后返回;
另外,我们还需要在es服务端的配置文件中配置快照路径path.repo,如下图配置:
好了,熟悉以上几个指令后,有没有发现,其实它们就是一些http请求指令,我们只要发给ES服务端处理就行。
这里,我们将es的操作命令封装成http请求,再使用CloseableHttpClient的execute()方法来执行HttpGet请求提交到ES服务器,通过解析返回信息判断处理结果。废话不多说,直接上代码:
/**
* 判断快照仓库是否存在
*
* @param repoName 仓库快照
* @return
* @throws Exception
*/
public boolean isSnapshotRepoExists(String repoName) throws Exception {
CloseableHttpClient client = HttpUtil.getClient();
HttpGet get = new HttpGet("http://127.0.0.1:9200/_snapshot/" + repoName);
CloseableHttpResponse response = null;
try {
response = client.execute(get);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_NOT_FOUND) {
return false;
}
throw new Exception("获取快照仓库失败!" + response.getStatusLine());
}
String result = EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8"));
JSONObject json = JSON.parseObject(result);
if (json.containsKey(repoName)) {
return true;
}
return false;
} catch (Exception e) {
throw e;
} finally {
releaseConnection(get, response);
}
}
/**
* 创建快照仓库
*
* @param repoName:仓库名称
* @param location:位置
*/
public void createSnapshotRepo(String repoName, String location) throws Exception {
CloseableHttpClient client = HttpUtil.getClient();
HttpPut put = new HttpPut("http://127.0.0.1:9200/_snapshot/" + repoName);
JSONObject sendObj = new JSONObject();
sendObj.put("type", "fs");
JSONObject settingObj = new JSONObject();
settingObj.put("location", location);
sendObj.put("settings", settingObj);
ByteArrayEntity entity = new ByteArrayEntity(sendObj.toJSONString().getBytes("UTF-8"));
entity.setContentType("application/json");
put.setEntity(entity);
CloseableHttpResponse response = null;
try {
response = client.execute(put);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
throw new Exception("创建备份仓库失败!" + response.getStatusLine());
}
String result = EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8"));
if (result.indexOf("acknowledged") == -1 || result.indexOf("true") == -1) {
throw new Exception("创建备份仓库失败!" + result);
}
} catch (Exception e) {
throw e;
} finally {
releaseConnection(put, response);
}
}
/**
* 创建快照
*
* @param repoName:快照仓库名称
* @param snapshotName:快照名称
*/
public void createSnapshot(String repoName, String snapshotName) throws Exception {
CloseableHttpClient client = HttpUtil.getClient();
HttpPut put = new HttpPut("http://127.0.0.1:9200/_snapshot/" + repoName + "/" + snapshotName + "?wait_for_completion=true");
//特殊操作,设置超时
RequestConfig.Builder requestConfig = RequestConfig.custom();
requestConfig.setConnectTimeout(5000);
requestConfig.setConnectionRequestTimeout(5000);
requestConfig.setSocketTimeout(360000);
put.setConfig(requestConfig.build());
CloseableHttpResponse response = null;
try {
response = client.execute(put);
if (response.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
throw new Exception("创建快照失败!" + response.getStatusLine());
}
String result = EntityUtils.toString(response.getEntity(), Charset.forName("UTF-8"));
JSONObject retObj = JSON.parseObject(result);
JSONObject snapshotObj = retObj.getJSONObject("snapshot");
if (snapshotObj.containsKey("snapshot") && snapshotObj.getString("snapshot").equals(snapshotName)) {
System.out.println("创建快照成功!");
return;
}
throw new Exception("创建快照失败!" + result);
} catch (Exception e) {
throw e;
} finally {
releaseConnection(put, response);
}
}
接下来,我们在main方法执行,三步走来测试测试:
public static void main(String[] args){
logger.info("正在开始备份.....");
long start = System.currentTimeMillis();
Date date = new Date();
String backupNo = "esBak_" + DateUtil.formatDate(date, "yyyyMMdd_HHmmss");
logger.info("正在备份ES....");
boolean repoExists = isSnapshotRepoExists("es_repo_es");
if (!repoExists) {
logger.info("ES备份仓库不存在,正在新建...");
createSnapshotRepo(BizConstants.ES_REPO_NAME, BizConstants.ES_BAK_PATH);
logger.info("ES备份仓库创建成功!");
}
createSnapshot(BizConstants.ES_REPO_NAME, backupNo);
logger.info("ES备份完成。耗时:" + (System.currentTimeMillis() - start) / 1000.0 + "秒");
}
执行之后,通过控制台查看输出日志,备份成功,我们再看看备份目录,也可以找到几个关键的文件及目录。至此,通过java实现ES进行数据备份测试通过,下一篇,再聊一聊如何通过快照实现还原。
下篇:Java 实现 Elasticsearch2.X 数据备份及还原(二)
【转载请注明出处——大道迷途】