ELASTIC的备份与恢复
前言
elasticsearch官方并没有提供合适的备份工具,然而生产场景中备份却是的确需要的。
本文介绍了使用自己写的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);
}
索引增量备份
#!/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 &
<?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的备份与恢复的更多相关文章
- Elastic认证考试,请先看这一篇
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/wojiushiwo987/article ...
- MySQL 数据库的备份与恢复
一.MySQL 常见的备份方式 1. 直接拷贝数据库文件(物理拷贝) 2. 使用 mysqldump 工具备份 3. 使用 mysqlhotcopy 工具备份 4. 使用 mysql 的主从同步复制, ...
- elastic search使用总结
1. elasticsearch安装 官方下载地址:https://www.elastic.co/downloads/elasticsearch 解压文件 elasticsearch-2.4.0.zi ...
- 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 ...
- ZTE交换路由设备配置的备份与恢复
一.TFTP服务器搭建 使用用户计算机搭建TFTP服务器,交换路由设备作为TFTP客户端. 运行TFTPServer.exe,该程序所在的目录为TFTP的根目录. 请保证您的TFTP可以Ping通所要 ...
- mysql数据库的备份与恢复
假定我们的目标数据库是 test, 表是 user.假定mysql的用户名和密码均为 root. 备份与恢复所用的程序分别是mysql软件包提供的 mysqldump 命令和 mysql 命令.思想很 ...
- Oracle逻辑备份与恢复
1. 备份的类型 按照备份方式的不同,可以把备份分为两类: 1.1 逻辑备份:指通过逻辑导出对数据进行备份.将数据库中的用户对象导出到一个二进制文件中,逻辑备份使用导入导出工具:EXPDP/IMP ...
- 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 ...
- RMAN备份与恢复之初入茅庐
理解数据库备份 所谓备份实际上是把数据库复制到转储设备的过程. 从备份方式来看数据库备份分为物理备份和逻辑备份,物理备份是把构成数据库的所有文件拷贝到指定的位置的过程,而逻辑备份只是利用SQL语言从数 ...
随机推荐
- 自定义泛型_无多态_通配符无泛型数组_jdk7泛型使用
通配符 T, K, V, E 等泛型字母为有类型, 类型参数赋予具体的值 ? 未知类型 类型参数赋予不确定值, 任意类型 只能用在 声明类型上,方法参数上, 不能用在定义泛型类上 上限 extends ...
- [转载]五理由 .NET开发者应该关注HTML 5
http://developer.51cto.com/art/201107/275039.htm
- c++刷题(43/100)矩阵旋转打印
题目1:矩阵旋转打印 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 则 ...
- lucene中文分词——(四)
1.分析器的执行过程:
- QTP图片验证/图片比较/二进制流对比法
图片验证主要是文件对比,其中我们可以利用二进制的方法读取图片信息,然后进行对比,达到对比的效果,本例子利用fso对象的文件流的方法实现,代码如下: Public Function CompareFil ...
- win7下PHP+MySQL+CoreSeek中文检索引擎配置
1.Windows下的coreseek安装测试 (64位win7旗舰版) 官方参考:http://www.coreseek.cn/products-install/install_on_windows ...
- ajax请求成功但不执行success-function回调函数的问题
在success:function(data){}下面加个error:function(){},看看是不是出错了走了error.如果是,说明返回值类型不符合要求. 比如:下面代码返回String类型. ...
- orm 缺点
背景 提起orm,在我开发这几年可是阴魂不散,因为我的开发没人带,全是自己琢磨,好处是很多东西都懂,都理解的透彻,缺点是见得少,接触少.而我一直没用orm,但是又到处听说orm,但我总想不明白有啥用处 ...
- Python_oldboy_自动化运维之路_paramiko,mysql(十二)
本节内容: paramiko mysql 1.paramiko http://www.cnblogs.com/wupeiqi/articles/5095821.html paramiko是一个模块,s ...
- Java中抽象类概述
抽象类 1.抽象类的定义 抽象类是为子类提供一个规范,这就必须联系到继承: 抽象类的制定就是让子类继承的: public abstract 类名{ //类体 //抽象方法 修饰符 abstract ...