一、环境准备
1.1 搭建 NFS 共享存储(用于存放快照文件)
在 NFS 服务端(例如 IP 192.168.100.100)安装并配置:
bash
# 安装 NFS 服务
yum install nfs-utils -y
# 创建共享目录
mkdir -p /data/share
# 配置 exports(允许 172.16.19.0/24 网段读写)
cat > /etc/exports <<EOF
/data/share 192.168.100.0/24(rw,sync,no_subtree_check,no_root_squash,insecure)
EOF
# 启动并设置开机自启
systemctl start nfs-server
systemctl enable nfs-server
exportfs -ra
1.2 在每个 Elasticsearch 节点上挂载 NFS
bash
# 安装 NFS 客户端
yum install nfs-utils -y
# 创建挂载点
mkdir -p /opt/nfs
# 挂载 NFS(假设服务端 IP 为 192.168.100.100)
mount 192.168.100.100:/data/share /opt/nfs
# 设置开机自动挂载(可选)
echo "192.168.100.100:/data/share /opt/nfs nfs defaults 0 0" >> /etc/fstab
1.3 调整目录权限
Elasticsearch 默认以 elasticsearch 用户运行,必须赋予该用户写入权限:
bash
chown -R elasticsearch:elasticsearch /opt/nfs
chmod 755 /opt/nfs
1.4 配置 Elasticsearch 仓库路径
编辑每个节点的 elasticsearch.yml,添加:
yaml
path.repo: ["/opt/nfs"]
重启 Elasticsearch 服务(每个节点依次重启,节点恢复后再启动另外一个节点):
bash
systemctl restart elasticsearch
二、创建快照仓库
在任意节点上执行,定义仓库名称为 ESbak_nfs,类型为 fs(文件系统):
bash
curl -XPUT -H 'Content-Type: application/json' localhost:9200/_snapshot/ESbak_nfs -d '{
"type": "fs",
"settings": {
"location": "/opt/nfs"
}
}'
查看已创建的仓库:
bash
curl -XGET "localhost:9200/_snapshot/_all"
三、准备测试数据(可选)
为验证备份恢复功能,可写入 1000 条测试数据到索引 index:
bash
for i in {1..1000}; do
echo '{"index":{"_index":"index"}}'
echo "{\"id\":$i,\"name\":\"user$i\",\"timestamp\":\"$(date -Iseconds)\"}"
done | curl -XPOST "http://localhost:9200/_bulk" -H "Content-Type: application/json" --data-binary @-
确认文档数量:
bash
curl -XGET "http://localhost:9200/index/_count"
四、创建快照备份
4.1 备份所有索引(包含集群状态)
bash
curl -XPUT "localhost:9200/_snapshot/ESbak_nfs/snapshot_all?wait_for_completion=true"
4.2 备份指定索引(推荐)
只备份名为 index 的索引,不备份集群全局状态:
bash
curl -XPUT "localhost:9200/_snapshot/ESbak_nfs/202605271422?wait_for_completion=true" \
-H "Content-Type: application/json" \
-d '{
"indices": "index",
"ignore_unavailable": true,
"include_global_state": false
}'
indices:支持通配符和逗号分隔,如"index1,index2"或"log-*"。ignore_unavailable:当指定索引不存在或关闭时忽略错误。include_global_state:设为false只备份索引数据,避免还原时覆盖模板、ILM 策略等。
4.3 备份执行结果示例
成功时会返回 JSON 响应,其中 "state":"SUCCESS" 表示成功:
json
{
"snapshot": {
"snapshot": "202605271422",
"state": "SUCCESS",
"shards": {"total": 6, "failed": 0, "successful": 6}
}
}
五、验证备份
5.1 查看单个快照信息
bash
curl -XGET "localhost:9200/_snapshot/ESbak_nfs/202605271422"
5.2 列出仓库所有快照
bash
curl -XGET "localhost:9200/_snapshot/ESbak_nfs/_all"
5.3 查看快照中各索引分片状态
bash
curl -XGET "localhost:9200/_snapshot/ESbak_nfs/202605271422/_status"
六、从快照恢复
6.1 恢复到同集群的另一个索引(不覆盖原索引)
bash
curl -XPOST "localhost:9200/_snapshot/ESbak_nfs/202605271422/_restore" \
-H "Content-Type: application/json" \
-d '{
"indices": "index",
"rename_pattern": "index",
"rename_replacement": "index_restored",
"include_global_state": false
}'
恢复完成后,新索引 index_restored 拥有原快照的全部数据。
6.3 跨集群迁移(备份转移到新集群)
步骤一:将 NFS 目录下的快照文件复制到新集群可访问的共享存储
假设新集群使用相同的 NFS 路径 /opt/nfs,只需确保新集群各节点能挂载同一 NFS 共享(或复制整个目录)。
步骤二:新集群同样配置 path.repo 并重启
在每台新节点上执行:
bash
mkdir -p /opt/nfs
mount 192.168.100.100:/data/share /opt/nfs
chown elasticsearch:elasticsearch /opt/nfs
echo "path.repo: [\"/opt/nfs\"]" >> /etc/elasticsearch/elasticsearch.yml
systemctl restart elasticsearch
步骤三:新集群创建同名仓库并恢复
bash
# 创建仓库(与旧集群配置完全相同)
curl -XPUT -H 'Content-Type: application/json' localhost:9200/_snapshot/ESbak_nfs -d '{
"type": "fs",
"settings": {"location": "/opt/nfs"}
}'
# 验证快照已自动发现
curl -XGET "localhost:9200/_snapshot/ESbak_nfs/_all"
# 恢复索引
curl -XPOST "localhost:9200/_snapshot/ESbak_nfs/202605271422/_restore" \
-H "Content-Type: application/json" \
-d '{
"indices": "index",
"include_global_state": false
}'
七、常见问题及解决方案
7.1 access_denied_exception
现象 :failed to update snapshot in repository ... /opt/nfs/meta-*.dat (Permission denied)
原因:Elasticsearch 进程对 NFS 目录无写权限。
解决:
- 确保 NFS 导出选项包含
rw且客户端挂载为读写模式(mount | grep /opt/nfs应含rw)。 - 修改目录所有者为
elasticsearch并设置 755 权限。 - 如果已挂载为只读,重新挂载:
mount -o remount,rw /opt/nfs
7.2 快照包含非预期的系统索引
现象 :备份时尽管只指定 "indices":"index",返回结果中仍出现 .ds-*、.geoip_databases 等索引。
原因 :未设置 "include_global_state":false 时,快照可能自动包含数据流及系统索引。
解决 :在创建快照的请求中明确添加 "include_global_state": false。
7.3 恢复时提示索引已存在
现象 :"reason": "cannot restore index [index] because an open index with same name already exists"
解决 :按 6.2 节先删除原索引,或使用 rename_pattern / rename_replacement 恢复到不同名称。
八、最佳实践建议
- 定期验证:生产环境应定期执行恢复演练,验证快照完整性。
- 命名规范 :快照名称建议包含日期时间(如
snapshot_20260527_1422),便于管理。 - 仅备份必要数据 :通过
indices参数仅备份业务索引,避免系统索引和无关数据。 - 使用共享存储:多节点集群必须使用共享文件系统(NFS、HDFS、S3 等),否则快照无法被所有节点访问。
- 监控磁盘空间:快照目录需预留足够容量,可配合 ILM 自动清理旧快照。
九、总结
利用 Elasticsearch 的快照功能结合 NFS 共享存储,可以高效实现:
- 指定索引的定时备份
- 同集群内快速恢复或克隆索引
- 跨集群数据迁移(更换集群、升级版本等)
通过以上步骤,您可以安全、可控地管理 Elasticsearch 索引的生命周期,确保数据高可用性。