前言

elasticsearch官方并没有提供合适的备份工具,然而生产场景中备份却是的确需要的。

本文介绍了使用自己写的php脚本以及第三方工具来进行索引的备份,恢复以及删除等操作。

全量备份

elasticdump --input  http://127.0.0.1:9200/logstash-postback --output  logstash-postback_2017.01.17.json --limit 1000
 
elasticdump安装方法在下面

恢复

命令例子
elasticdump --input logstash-postback_2017.01.14.json --output http://127.0.0.1:9200/logstash-postback --limit 1000
详解
elasticdump命令需要单独安装。
--input 是指定输入,可指定文件,或需要备份的es集群。
--output是指定输出,可指定文件,或需要备份的es集群。
logstash-postback_2017.01.14.json  是指定的已备份的文件。
 http://127.0.0.1:9200/logstash-postback  是指定的要恢复数据的elastictic集群,IP加端口加索引名。注意,索引名是不带时间的。
--limit 1000 一次导入一千条数据,加快进度。
 
elasticdump命令安装
yum install npm
npm install elasticdump -g
命令安装完毕,可以测试。
可能会报出nodejs的版本之类的错误,你需要升级一下版本。
npm install -g n
n stable
至此可以使用。
 

删除索引

 php delete.php --index http://127.0.0.1:9200/<index> --start 2017-01-01 --end 2017-01-02  
--start 选择删除这个索引中指定日期的内容
--end 不传则默认删除一天,也就是start的那天
<index> 要删除的索引名
 
cat delete.php
 
<?php
date_default_timezone_set('Asia/Shanghai'); $longopts = array(
'index:',
'query:',
'start:',
'end:',
);
$options = getopt('a', $longopts); if(!isset($options['index'])) {
fwrite(STDERR, "index必须设置索引地址\n");
exit(1);
} $components = parse_url($options['index']);
if(!isset($components['path'])) {
fwrite(STDERR, 'index不可为空');
exit(1);
} $host = "{$components['scheme']}://{$components['host']}:{$components['port']}";
$index = basename($components['path']); $query = isset($options['query']) ? $options['query'] : '{"query":{"match_all":{}}}';
if(isset($options['start'])) {
$start_time = strtotime($options['start']);
$start = date('Y-m-d', $start_time).'T00:00:00+0800';
if(isset($options['end'])) {
$end_time = strtotime($options['end']);
$end = date('Y-m-d', $end_time).'T00:00:00+0800';
} else {
$end = date('Y-m-d', $start_time+86400).'T00:00:00+0800';
} $field = strpos($index, 'analysis')!==false ? 'create_time' : 'date';
$query = '{"size":1000,"_source":false,"query":{"filtered":{"filter":{"range":{"'.$field.'":{"gte":"'.$start.'","lt":"'.$end.'"}}}}}}';
} $scroll_id = null;
$retry = 0;
$num = 0;
while(true) {
if(is_null($scroll_id)) {
$result = post("{$host}/{$index}/_search?scroll=2m", $query);
} else {
$result = get("{$host}/_search/scroll?scroll=2m&scroll_id={$scroll_id}");
} $json = json_decode($result, true);
if(!isset($json['_scroll_id'])) {
fwrite(STDERR, "查询失败:索引-{$index} 起始-{$start} 截止-{$end}\n");
sleep(5);
$retry++;
if($retry>10) {
exit(4);
}
} $scroll_id = $json['_scroll_id'];
$bulk = [];
foreach($json['hits']['hits'] as $row) {
unset($row['_score']);
$bulk[] = json_encode(['delete'=>$row]);
$num++;
} if(count($json['hits']['hits'])==0)
{
break;
} $check = post("{$host}/_bulk", implode("\n", $bulk)."\n");
fwrite(STDOUT, "{$num}\n");
usleep(100000);
} echo "deleted:{$num}\n"; function get($url)
{
$handle = curl_init();
//curl_setopt($handle, CURLOPT_POST, 1);
curl_setopt($handle, CURLOPT_HEADER, 0);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($handle, CURLOPT_URL, $url);
//curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
return curl_exec($handle);
} function post($url, $data)
{
$handle = curl_init();
curl_setopt($handle, CURLOPT_POST, 1);
curl_setopt($handle, CURLOPT_HEADER, 0);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
return curl_exec($handle);
}
 

索引增量备份

elasticdump增量备份有BUG,无规律的丢数据。
于是我们自己写了脚本来进行增量备份。
备份脚本分为两个部分,PHP脚本沟通elasticsearch来进行数据读取与备份。SHELL脚本来写作传参与PHP脚本
 
SHELL脚本如下
 
#!/bin/bash

#如果有参数,则第一个参数为备份日期,否则默认备份昨天数据
if [ -z "$1" ];then
start=$(date +%Y-%m-%d --date '-1 day 00:00:00')
end=$(date +%Y-%m-%d --date 'today 00:00:00')
else
start=$(date +%Y-%m-%d --date $)
end=$(date +%Y-%m-%d --date "$1 +1 day 00:00:00")
fi #如果是每月1号则加一天,解决时区导致的数据跨索引问题
if [ $(date +%d --date $end) -eq "" ]
then
end=$(date +%Y-%m-%d --date "$end +1 day 00:00:00")
fi php esdump.php --input=http://127.0.0.1:9200/logstash-event-$(date +%Y.%m --date $start) --start $start --end $end 2>> backup_error_$start.log | gzip > event/logstash-event-$(date +%Y.%m_%d --date $start).json.gz 2>> backup_error_$start.log &
 
注:代码第18行的logstash-event替换为你要备份的索引名
 
PHP脚本如下(无需修改)
<?php
date_default_timezone_set('Asia/Shanghai'); $longopts = array(
'input:',
'output:',
'query:',
'start:',
'end:',
);
$options = getopt('a', $longopts); if(!isset($options['input'])) {
fwrite(STDERR, "input必须设置索引地址\n");
exit(1);
} $check = get($options['input'].'/_count');
if($check===false) {
fwrite(STDERR, "input索引地址无效:{$options['input']}\n");
exit(2);
} $check = json_decode($check, true);
if(!isset($check['count'])) {
fwrite(STDERR, "input索引地址无效:{$options['input']}\n");
exit(3);
} $components = parse_url($options['input']);
$host = "{$components['scheme']}://{$components['host']}:{$components['port']}";
$index = basename($components['path']); $query = isset($options['query']) ? $options['query'] : '{"query":{"match_all":{}}}';
if(isset($options['start'])) {
$start_time = strtotime($options['start']);
$start = date('Y-m-d', $start_time).'T00:00:00+0800';
if(isset($options['end'])) {
$end_time = strtotime($options['end']);
$end = date('Y-m-d', $end_time).'T00:00:00+0800';
} else {
$end = date('Y-m-d', $start_time+86400).'T00:00:00+0800';
} $field = strpos($index, 'analysis')!==false ? 'create_time' : 'date';
$query = '{"size":1000,"sort":{"'.$field.'":{"order":"asc"}},"query":{"filtered":{"filter":{"range":{"'.$field.'":{"gte":"'.$start.'","lt":"'.$end.'"}}}}}}'; if(strpos($index, 'eventlogs')!==false) {
$query = '{"size":1000,"sort":{"'.$field.'":{"order":"asc"}},"query":{"filtered":{"filter":{"bool":{'.
'"must":[{"range":{"date":{"gte":"'.$start.'","lte":"'.$end.'"}}}],'.
'"must_not":[{"exists": {"field":"nsp3hq"}},{"exists": {"field":"q0i8u1"}},{"exists": {"field":"eyn916"}},{"exists": {"field":"20mqd8"}},'.
'{"exists": {"field":"wwbkux"}},{"exists": {"field":"r5ua96"}},{"exists": {"field":"easiz"}},{"exists": {"field":"dexusu"}},{"exists": {"field":"earts"}},'.
'{"exists": {"field":"ealu"}},{"exists": {"field":"ealf"}},{"exists": {"field":"eal"}},{"exists": {"field":"ears"}},{"exists": {"field":"ealuf"}},'.
'{"exists": {"field":"ealus"}},{"exists": {"field":"eaatf"}},{"exists": {"field":"enail"}},{"exists": {"field":"enuail"}},{"exists": {"field":"test"}}]'.
'}}}}}';
}
} $scroll_id = null;
$retry = 0;
$num = 0;
while(true) {
if(is_null($scroll_id)) {
$result = post("{$host}/{$index}/_search?scroll=2m", $query);
} else {
$result = get("{$host}/_search/scroll?scroll=2m&scroll_id={$scroll_id}");
} $json = json_decode($result, true);
if(!isset($json['_scroll_id'])) {
fwrite(STDERR, "查询失败:索引-{$index} 起始-{$start} 截止-{$end}\n");
sleep(5);
$retry++;
if($retry>10) {
exit(4);
}
} $scroll_id = $json['_scroll_id']; foreach($json['hits']['hits'] as $row) {
fwrite(STDOUT, json_encode($row)."\n");
$num++;
} if(count($json['hits']['hits'])==0)
{
break;
} usleep(100000);
} //校验条数是否一致
$query = json_decode($query, true);
unset($query['size'], $query['sort']);
$result = post("{$host}/{$index}/_count", json_encode($query));
$json = json_decode($result, true);
if(!isset($json['count']) or intval($json['count'])!==$num) {
fwrite(STDERR, "校验失败:索引-{$index} 起始-{$start} 截止-{$end} 记录条数-{$json['count']} 导出条数-{$num}\n");
} function get($url)
{
$handle = curl_init();
//curl_setopt($handle, CURLOPT_POST, 1);
curl_setopt($handle, CURLOPT_HEADER, 0);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($handle, CURLOPT_URL, $url);
//curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
return curl_exec($handle);
} function post($url, $data)
{
$handle = curl_init();
curl_setopt($handle, CURLOPT_POST, 1);
curl_setopt($handle, CURLOPT_HEADER, 0);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
return curl_exec($handle);
}

备份时执行shell脚本即可备份昨天的增量数据

谢土豪

如果有帮到你的话,请赞赏我吧!

本文为kerwin原创,转载请注明出处。

http://www.cnblogs.com/kerwinC/p/6296675.html

ELASTIC的备份与恢复的更多相关文章

  1. Elastic认证考试,请先看这一篇

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/wojiushiwo987/article ...

  2. MySQL 数据库的备份与恢复

    一.MySQL 常见的备份方式 1. 直接拷贝数据库文件(物理拷贝) 2. 使用 mysqldump 工具备份 3. 使用 mysqlhotcopy 工具备份 4. 使用 mysql 的主从同步复制, ...

  3. elastic search使用总结

    1. elasticsearch安装 官方下载地址:https://www.elastic.co/downloads/elasticsearch 解压文件 elasticsearch-2.4.0.zi ...

  4. Assign an Elastic IP Address to Your Instance

    By default, an instance in a nondefault VPC is not assigned a public IP address, and is private.You ...

  5. ZTE交换路由设备配置的备份与恢复

    一.TFTP服务器搭建 使用用户计算机搭建TFTP服务器,交换路由设备作为TFTP客户端. 运行TFTPServer.exe,该程序所在的目录为TFTP的根目录. 请保证您的TFTP可以Ping通所要 ...

  6. mysql数据库的备份与恢复

    假定我们的目标数据库是 test, 表是 user.假定mysql的用户名和密码均为 root. 备份与恢复所用的程序分别是mysql软件包提供的 mysqldump 命令和 mysql 命令.思想很 ...

  7. Oracle逻辑备份与恢复

      1. 备份的类型 按照备份方式的不同,可以把备份分为两类: 1.1 逻辑备份:指通过逻辑导出对数据进行备份.将数据库中的用户对象导出到一个二进制文件中,逻辑备份使用导入导出工具:EXPDP/IMP ...

  8. How to ssh to your Amazon Elastic Beanstalk instance?

    Well, if it's ec2 or a digital ocean server, it would be a lot easier- you do what you normally do f ...

  9. RMAN备份与恢复之初入茅庐

    理解数据库备份 所谓备份实际上是把数据库复制到转储设备的过程. 从备份方式来看数据库备份分为物理备份和逻辑备份,物理备份是把构成数据库的所有文件拷贝到指定的位置的过程,而逻辑备份只是利用SQL语言从数 ...

随机推荐

  1. 机器学习:分类算法性能指标之ROC曲线

    在介绍ROC曲线之前,先说说混淆矩阵及两个公式,因为这是ROC曲线计算的基础. 1.混淆矩阵的例子(是否点击广告): 说明: TP:预测的结果跟实际结果一致,都点击了广告. FP:预测结果点击了,但是 ...

  2. [原]Android开发优化-Adapter优化

    ListView作为Android开发中使用频率最高的一个控件,保证ListView的流畅运行,对用户体验的提高至关重要.Adapter是ListView和数据源之间的中间人,当每条数据进入可见区时, ...

  3. ASP.NET私有构造函数作用

    一.私有构造函数的特性 1.一般构造函数不是私有或者保护成员,但构造函数可以使私有成员函数,在一些特殊的场合,会把构造函数定义为私有或者保护成员. 2.私有构造函数是一种特殊的实例构造函数.它通常用在 ...

  4. AngularJs -- 指令简介

    整理书籍内容(QQ:283125476 发布者:M [重在分享,有建议请联系->QQ号]) HTML文档 HTML文档是一个纯文本文件,包含了页面的结构以及由CSS定义的样式,或者可以操作样式的 ...

  5. AngularJs -- 模 块

    在JavaScript中,将函数代码全部定义在全局命名空间中绝对不是什么好主意,这样做会导致冲突从而是调试变得非常困难,浪费宝贵的时间. 上一章介绍数据绑定时,就是写在全局命名空间中定义的函数. 在A ...

  6. java关于图片处理修改图片大小

    最近做了一个关于图片浏览的内容.因为图片都是一些证件的资料的扫描件所以比较大,对系统的影响也是非常之大的,有很大可能直接把系统干死.那么我是这么处理的,给大家分享一下.如果大家有好的方案的话一定要早点 ...

  7. UVALive 6176 Faulhaber's Triangle

    题目链接 http://acm.sdibt.edu.cn/vjudge/ojFiles/uvalive/pdf/61/6177.pdf 题意是  给定一个数n,代表着一共有n个人,且他们的身高从1到n ...

  8. zabbix user parameters和Loadable modules的使用方法介绍

    目录 需求 实现 原理 前端配置 后端配置 shell实现 python实现 C实现 需求: 采集主机的-/+ buffers/cache  free的数据 实现: 采集/proc/meminfo中的 ...

  9. bellman-ford算法(判断有没有负环)

    #include <iostream> #include <vector> #include<string> #include<cstring> usi ...

  10. python-super1

    一.问题的发现与提出 一般子类在继承父类后,若子类覆盖了父类,则只执行子类,不执行父类.如果没有,则执行父类代码. 发现使用super()后,子类,父类都会执行,比较疑惑,记录学习,super知识点 ...