Easticsearch从0学到1之nfs快照备份与恢复
背景
(1)场景1:笔者在之前做晋升答辩的时候,被提到这样一个需求:“ES能不能够在需要的时候,把去年的数据快速加载进来能够查询”。由于,鄙人当时紧张直接回答:“因为用ES我们主要是用于对日志查询和分析的,日志量比较大,保存时间较短;最简单的做法,就是把数据先储存在其他的地方,然后用logstash或其他插件打进ES”。其实解决这个问题还有其他办法,如果不是日志场景,数据量不大,我们完全可以把索引close掉,在需要的时候再把他open,就可以实现快速使索引的数据处于可搜索状态。
(2)场景2:我们的日志保存周期一般都比较短,会有周期性的清理策略。但是最近业务方给我们提需求了,他们需要上一个月的日志。因为当时在HDFS中有原日志文件,所以当时决定从hdfs中读取数据到ES中,当时就一顿的找工具如官方提供的ES-Hadoop,比如Alibaba的DataX,其中官网提供的ES-Hadoop需要需要自己写job,经过实践这两种方法都不太好使。最后决定直接用logstash进行读取原日志文件,因为我们的日志文件,压缩了两层分别为tar.gz和第二层log.gz;所以我们需要先解压然后再用logstash去消费,并且由于当时资源紧张只有一台空闲机器供logstash使用,磁盘只有2T左右若所有压缩包全部解压,磁盘百分之两千不够用,所以只能消费完一个解压包之后再解压一个压缩包;问题来了,我不可能一直去盯着有没有消费完,然后再去手动解压哈,于是自己又写了一个shell脚本实现全自动化。最后也算是完成任务了。
以上两个场景让我意识到一个问题,那就是ES数据的备份问题(当然数据备份不是解决上述场景的唯一方法,但是不失为一个途径)。ES不是一个完全做存储的数据库系统,它的主要应用场景是搜索和数据分析,但是对数据做备份也是有必要的。Elasticsearch的副本只是提高可靠性,但是无法应对灾难性故障,因此备份集群对应对一些灾难性事故也是有重要的意义。
ES集群备份方案
双ES集群(或一个集群划分成两个域)
这里我们只讲双ES集群的:假设cluster1存储近几天的日志,cluster2存储近一个月的日志。
对于cluster2集群的要求,特别要求磁盘足够大,在cluster2中对于不用的索引close掉,避免其占用内存。每天凌晨通过remote reindex的方式,把cluster1中的数据导入到cluster2中。
前提:需要一个冷备集群
缺点:机器资源成本
测试:目前功能测试已通过,可行。remote reindex的速度,性能方面还未测试。
快照
快照的原理,本文不做过多介绍,想要了解的同学建议阅读《ELASTICSEARCH 源码解析与优化实战》样章-第 13 章 SNAPSHOT 模块分析。
使用快照的方式,前提必须要有一个快照仓库。官网给出了以下的仓库类型:
- 共享文件系统,比如 NAS
- Amazon S3
- HDFS (Hadoop 分布式文件系统) ,ES对HDFS 有版本的要求
- Azure Cloud
下面我们将重点介绍一下是共享文件的方式进行快照:nfs作为快照仓库,在官网上的介绍并不是特别详细,没有说明如何去搭建一个共享文件的仓库。
前提:准备一台机器,磁盘大约能容纳大于一个月日志一半的量。
优点:快照的方式,不用去存储原始数据,并且创建索引的那些元信息也都有保存。
测试:测通可行,恢复速度较慢。
共享文件系统支持以下配置
参数 | 简介 |
---|---|
location | 指定了一个已挂载的目的地址 |
compress | 是否开启压缩。压缩仅对元数据进行(mapping 及 settings),不对数据文件压缩。默认为 true |
chunk_size | 传输文件时数据被分解为块,此处配置块大小,单位为字节默认为 null(无限块大小) |
max_snapshot_bytes_per_sec | 快照操作时节点间限速值,默认40mb |
max_restore_bytes_per_sec | 从快照恢复时节点间限速值,默认40mb |
readonly | 设置仓库属性为只读。默认为 false |
nfs方式快照的备份与恢复的实践过程如下。
实践
软件环境
本次实践的环境是在centos7下,并且在三台机器上安装了Elasticsearch集群,详细如下:
查看 linux版本
cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)
Elasticsearch 6.4.0
其中机器158,166,44机器已经安装Elasticsearch。173为空闲的磁盘较大的机器。
客户端机器
192.99.71.158
192.99.71.166
192.99.71.44
服务端机器
192.99.71.173
nfs仓库搭建
服务端
安装nfs服务
yum install -y nfs-utils
在NFS服务端173机器上,编辑vim /etc/exports
文件,添加/data/elasticsearch_back
目录配置有哪些权限。
/data/elasticsearch_back *(insecure,rw,no_root_squash,sync)
NFS服务做成开机启动
systemctl enable rpcbind.service
systemctl enable nfs-server.service
启动NFS相应的服务
systemctl start rpcbind.service
systemctl start nfs-server.service
确认服务是否启动
rpcinfo -p
创建用户,指定uid和用户组
添加用户组并指定gid
groupadd -g 598 elasticsearch
添加用户
useradd -u 664 -g elasticsearch elasticsearch
改变目录所属组合用户
chown -R /data/elasticsearch_back
客户端
查看服务端共享目录
showmount -e 192.99.71.173
返回如下信息
Export list for 192.99.71.173:
/data/elasticsearch_back *
在客户端158,166,44安装相应的服务,并启动
yum install -y nfs-utils
systemctl enable rpcbind.service
systemctl start rpcbind.service
分别在客户端机器158,166,44上挂载共享目录,将服务端共享目录挂载在客户端/data/es_data_back这个位置
mount -t nfs 192.90.71.173:/data/elasticsearch_back /data/es_data_back -o proto=tcp -o nolock
可以用命令**df -h
**命令进行验证
注意:
(1)目录/data/es_data_back
必须是的所属用户,必须是elastic用户。
(2)在elasticsearch.yml加入如下配置,即快照仓库所在位置。
path.repo: ["/data/es_data_back"]
(3)必须每个节点都要创建path.repo,因为索引的分片,数据是分布式的保存,要想快照到全部数据信息,必须每个节点都创建repo,并挂载到共享目录。
测试nfs是否挂载成功
在机器158,166,44或173的任意一台机器上,切换elastic用户,在/data/es_data_back或173的/data/elasticsearch_back下创建文件test.txt,在其他三台机器都能看到。如果实践失败则有可能是一下原因:
问题
四台机器的elasticsearch用户的uid不一致,gid也不一致,为什么会这样呢?实际上是因为你在其中一台机器创建test.txt文件时,其它机器在共享这个文件时,这个文件的uid和gid也被共享了,虽然你是用elasticsearch用户创建的test.txt文件,但是由于三台机器的elasticsearch用户uid和gid不一致,结果在不同机器上看到的用户和用户组不一致,这样就存在权限问题了,设想一下,你在使用snapshot备份的时候,在一台机器上创建了一个备份,而由于四台机器的用户uid和gid不一样在写入的时候,是不是会发生拒绝访问的问题。所以解决方法就是得确保四台机器的uid一致,gid也一致。
查看用户的GID与UID;cat /etc/passwd
,我们会找到下面的一条信息。
elasticsearch:x:664:598:elasticsearch user:/nonexistent:/sbin/nologin
elasticsearch:用户名
x 密码:字符x表示密码被加密保存在/etc/shadow文件中
664用户ID(UID):每个用户必需指定UID。UID 0是保留给root用户的,UID 1~99是保留给其它预定义用户的, UID 100~999是保留给系统用户的
598 组ID(GID):主组ID(保存在/etc/group文件中);
**elasticsearch:**用户ID信息,用户备注信息
解决办法
修改用户UID与GID
如下
elasticsearch 旧的 UID: 1005
elasticsearch 新的 UID: 644
elasticsearch 用户组名字: elasticsearch
elasticsearch所属组的旧 GID: 2000
elasticsearch所属组的新 GID: 598
步骤1 修改用户的UID
usermod -u 644 elasticsearch
步骤2 修改组的GID
groupmod -g 598 elasticsearch
elasticsearch用户的家目录下面的文件属主和属组会在1、2命令执行后自动修改成新的uid、gid对应的属主属组,但是其他文件目录需要手动修改
# find / -user 1005 -exec chown -h elasticsearch {} \;
# find / -group 2000 -exec chgrp -h elasticsearch {} \;
这样用户和组的uid、gid就修改好了。可以用id命令进行验证
# ls -l /home/elasticsearch/
# id -u elasticsearch
# id -g elasticsearch
# grep elasticsearch /etc/passwd
# grep elasticsearch /etc/group
再次进行测试应该不会出现问题了
快照与恢复
快照
创建快照仓库my_backup
PUT /_snapshot/my_backup
{
"type": "fs",
"settings": {
"location": "/data/es_data_back/back_up",
"compress": true
}
}
创建快照,对指定的两个索引进行快照,其中basiclog-pv_1001500-2019-03-26存储数据415MB
PUT _snapshot/my_backup/snapshot_20190329
{
"indices": "basiclog-pv_1001500-2019-03-26,basiclog-pv_1001500-2019-03-22"
}
获取快照信息,从下面的返回信息可知,创建快照一共耗费大约7秒
{
"snapshots": [
{
"snapshot": "snapshot_20190329",
"uuid": "TmebuVW7STKTVWCtnF2Fwg",
"version_id": 6040099,
"version": "6.4.0",
"indices": [
"basiclog-pv_1001500-2019-03-26",
"basiclog-pv_1001500-2019-03-22"
],
"include_global_state": true,
"state": "SUCCESS",
"start_time": "2019-03-29T03:49:21.775Z",
"start_time_in_millis": 1553831361775,
"end_time": "2019-03-29T03:49:28.369Z",
"end_time_in_millis": 1553831368369,
"duration_in_millis": 6594,
"failures": [],
"shards": {
"total": 10,
"failed": 0,
"successful": 10
}
}
]
}
做好快照之后,我们可以删除该索引
DELETE basiclog-pv_1001500-2019-03-26
恢复
恢复快照中指定的索引
POST /_snapshot/my_backup/snapshot_20190329/_restore
{
"indices": "basiclog-pv_1001500-2019-03-26"
}
获取快照恢复详细信息GET basiclog-pv_1001500-2019-03-26/_recovery
,大概耗费3秒左右;由于返回的信息太多,就只粘贴出部分信息;其中包含每个分片恢复的详细信息。
{
"basiclog-pv_1001500-2019-03-26": {
"shards": [
{
"id": 3,
"type": "SNAPSHOT",
"stage": "DONE",
"primary": true,
"start_time_in_millis": 1553831843645,
"stop_time_in_millis": 1553831846405,
"total_time_in_millis": 2759,
"source": {
"repository": "my_backup",
"snapshot": "snapshot_20190329",
"version": "6.4.0",
"index": "basiclog-pv_1001500-2019-03-26"
},
"target": {
"id": "Z0MGc4DkRKafvAnK8gJaTA",
"host": "192.99.71.44",
"transport_address": "10.90.71.44:9300",
"ip": "192.99.71.44",
"name": "bj-sjhl-log-es-test-3.test.xesv5.com"
},
"index": {
"size": {
"total_in_bytes": 43439670,
"reused_in_bytes": 0,
"recovered_in_bytes": 43439670,
"percent": "100.0%"
},
"files": {
"total": 67,
"reused": 0,
"recovered": 67,
"percent": "100.0%"
},
"total_time_in_millis": 2685,
"source_throttle_time_in_millis": 0,
"target_throttle_time_in_millis": 0
},
"translog": {
"recovered": 0,
"total": 0,
"percent": "100.0%",
"total_on_start": 0,
"total_time_in_millis": 56
},
"verify_index": {
"check_index_time_in_millis": 0,
"total_time_in_millis": 0
}
跨集群恢复
我们还可以把快照拷贝到其他的地方,在其他集群进行快照恢复。下面是我之前做过的一个测试。
方法一:
第一:在目标集群中,建议构建与源集群相同的path.repo
(elasticsearch.yml
中进行配置)
第二步:在目标集群创建和源集群一样的仓库
Put http://192.99.2.210:9200/_snapshot/my_backup
{
"type": "fs",
"settings": {
"location": "/data_es/backup_es/my_fs_backup",
"compress": true
}
}
第三步:在源集群,创建快照
第四步:把快照拷贝到目标集群中,与源集群备份仓库的对应,即把源集群/data_es/backup_es/
目录下的my_fs_backup,拷贝到目标集群的/data_es/backup_es/
第五步:快照恢复,与在源集群的恢复方式一样。如下是恢复snapshot_20190329
下全部的索引
POST http://192.99.2.210:9200/ _snapshot/my_backup/snapshot_20190329/_restore
方法二:
第一步、第二步和第三步以及第五步与方法一的步骤一样
第四步:断开源集群与nfs文件的挂载关系,把目标集群的path.repo
与服务端nfs建立挂载关系
参考文献
[1] https://mp.csdn.net/mdeditor/88894877
[2] https://www.elastic.co/guide/en/elasticsearch/reference/6.4/modules-snapshots.html
[2] Elasticsearch升级踩坑记之使用snapshot备份数据https://blog.csdn.net/u012062455/article/details/79570996
[3] CentOS6.6 NFS服务的安装与配置详解https://blog.csdn.net/wunianjiumeng/article/details/79067641
[4] 大数据量Elastic数据迁移方法及注意事项https://www.2cto.com/database/201610/557571.html
[5] Elasticsearch索引迁移的四种方式https://blog.csdn.net/laoyang360/article/details/65449407
[6] CentOS7.2 通过nfs设置共享文件夹 https://blog.csdn.net/rznice/article/details/72654826
[7] Elasticsearch:跨集群数据迁移之离线迁移 https://www.imooc.com/article/41844
[8] Linux umount命令 <http://www.runoob.com/linux/linux-comm-umount.html
[9] Linux 安装 Elasticsearch6.4.x 详细步骤以及问题解决方案http://blog.51cto.com/moerjinrong/2310817
[10] https://www.elastic.co/guide/en/elasticsearch/reference/6.5/modules-snapshots.html
[11] Elasticsearch–索引备份与迁移 https://blog.csdn.net/u014431852/article/details/52905821/
[12] elasticsearch快照和恢复https://blog.csdn.net/crazyhacking/article/details/45726683
[13] 修改GID与UIDhttps://blog.csdn.net/train006l/article/details/79007483
[14] https://www.cyberciti.biz/faq/linux-change-user-group-uid-gid-for-all-owned-files/
[15] <https://blog.csdn.net/jackailson/article/details/50993427