Java 实现 Elasticsearch2.X 数据备份及还原(一)

前几天,领导要求在现有系统上增加个数据(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,如下图配置:

Java 实现 Elasticsearch2.X 数据备份及还原(一)_第1张图片

好了,熟悉以上几个指令后,有没有发现,其实它们就是一些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 数据备份及还原(一)_第2张图片

Java 实现 Elasticsearch2.X 数据备份及还原(一)_第3张图片

下篇:Java 实现 Elasticsearch2.X 数据备份及还原(二)

【转载请注明出处——大道迷途】

你可能感兴趣的:(Elasticsearch,Java实现ES备份,Elasticsearch备份)