Elasticsearch 索引备份与恢复实践(基于 NFS 共享仓库)

一、环境准备

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 索引的生命周期,确保数据高可用性。

相关推荐
做个文艺程序员2 小时前
第09篇:ES 数据同步方案——Canal + Logstash + Flink 全方案对比与实战
大数据·elasticsearch·mysql同步es·es数据同步·flink实时同步·es增量同步
做个文艺程序员2 小时前
第04篇:Query DSL 全景与高级检索实战——从入门查询到复杂业务场景
elasticsearch·elasticsearch分词·elasticsearch检索
杰克尼11 小时前
天机学堂复习总结(day03-day04)
java·开发语言·redis·elasticsearch·spring cloud
一勺菠萝丶21 小时前
Git Tag 使用教程:如何打 Tag、切换 Tag、推送 Tag 和删除 Tag
大数据·git·elasticsearch
Elastic 中国社区官方博客1 天前
Kibana 中的 AI Chat 现在可以原生渲染仪表板
大数据·数据库·人工智能·elasticsearch·搜索引擎·云原生
Elastic 中国社区官方博客1 天前
Elastic 的 ML 与 AI Assistant 如何将 NOC 中 802.1x 故障排查时间从 20 分钟缩短到数秒
大数据·运维·人工智能·elasticsearch·搜索引擎·全文检索·可用性测试
Gavin-Wang1 天前
swift 项目 commit 规范
大数据·elasticsearch·搜索引擎
Wils0nEdwards2 天前
Windows本地 git 版本管理
windows·git·elasticsearch
不吃鱼的羊2 天前
提交代码添加Change-Id
大数据·elasticsearch·搜索引擎