Elasticsearch数据迁移快照方案初探(一):多节点集群配置踩坑记

背景介绍

在生产环境中,我们经常需要将测试环境的Elasticsearch索引数据迁移到生产环境。这次我们遇到了一个典型的多节点集群快照配置问题:需要为所有节点添加path.repo配置,但过程中遇到了各种挑战。

问题描述

我们的Elasticsearch集群包含6个节点:

  • Master节点: es-node1, es-node3
  • 数据节点: es-node2, es-node4, es-node5, es-node6

需要迁移的索引:

  • index_business_data: 8.8GB, 543,617个文档
  • index_embedding_data: 13.7GB, 367,067个文档

初始尝试:直接创建快照仓库

bash 复制代码
curl -X PUT "https://[ES_HOST]:9200/_snapshot/backup_repo" \
  -H "Content-Type: application/json" \
  -u "[USERNAME]:[PASSWORD]" \
  -k \
  -d '{
    "type": "fs",
    "settings": {
      "location": "/tmp/es_backup",
      "compress": true
    }
  }'

错误信息

json 复制代码
{
  "error": {
    "root_cause": [{
      "type": "repository_exception",
      "reason": "[backup_repo] location [/tmp/es_backup] doesn't match any of the locations specified by path.repo because this setting is empty"
    }]
  }
}

问题分析

错误的核心原因是:Elasticsearch集群没有配置path.repo参数。这个参数指定了快照文件的存储路径,必须预先配置才能创建快照仓库。

解决方案选择

我们面临两个选择:

  1. 配置快照功能 :为所有节点添加path.repo配置
  2. 使用elasticsearch-dump:直接导出数据

考虑到数据完整性和长期维护,我们选择了第一种方案。

Docker环境下的配置挑战

我们的Elasticsearch运行在Docker容器中,这带来了额外的复杂性:

挑战1:配置修改需要重启

  • docker restart无法覆盖环境变量
  • 必须使用docker-compose down + up -d
  • 需要逐个重启节点,避免集群不可用

挑战2:数据节点重启策略

bash 复制代码
# 推荐的重启顺序
# 1. 先重启数据节点(分批)
docker stop es-node5 es-node6
docker start es-node5 es-node6
sleep 40

docker stop es-node2 es-node4
docker start es-node2 es-node4
sleep 40

# 2. 最后重启master节点(逐个)
docker stop es-node1
docker start es-node1
sleep 40

docker stop es-node3
docker start es-node3
sleep 40

挑战3:分片重分配控制

为了避免重启过程中的分片迁移问题,我们采用了以下策略:

bash 复制代码
# 1. 禁用分片重分配
curl -X PUT "https://[ES_HOST]:9200/_cluster/settings" \
  -H "Content-Type: application/json" \
  -u "[USERNAME]:[PASSWORD]" \
  -k \
  -d '{
    "persistent": {
      "cluster.routing.allocation.enable": "none"
    }
  }'

# 2. 减少索引副本数
curl -X PUT "https://[ES_HOST]:9200/_all/_settings" \
  -H "Content-Type: application/json" \
  -u "[USERNAME]:[PASSWORD]" \
  -k \
  -d '{
    "index": {
      "number_of_replicas": 0
    }
  }'

配置修改过程

为每个节点添加快照配置:

yaml 复制代码
environment:
  # ... 其他配置 ...
  - path.repo=/opt/elasticsearch/snapshots

volumes:
  # ... 其他卷 ...
  - /opt/elasticsearch/snapshots:/opt/elasticsearch/snapshots

踩坑经验总结

  1. docker restart无法更新环境变量 :必须使用down + up
  2. 分片重分配控制很重要:避免重启过程中的数据迁移
  3. 逐个重启策略:确保集群始终可用
  4. 权限设置:快照目录需要正确的用户权限

配置验证

重启完成后,验证配置是否生效:

bash 复制代码
curl -k -u "[USERNAME]:[PASSWORD]" "https://[ES_HOST]:9200/_nodes/_all/settings" | grep -i "path.repo"

关键要点

  • 环境变量配置:Docker容器重启后环境变量不会自动更新
  • 集群状态管理:重启过程中需要控制分片重分配
  • 权限管理:快照目录需要正确的用户权限设置
  • 分批重启:避免同时重启多个节点导致集群不可用

问题解决思路总结

核心思路:

  1. 识别根本原因path.repo配置缺失
  2. 评估解决方案:快照配置 vs elasticsearch-dump
  3. 制定重启策略:分批重启,控制分片迁移
  4. 验证配置生效:确认所有节点配置一致

关键决策点:

  • 选择快照方案而非直接导出
  • 采用分批重启而非同时重启
  • 使用分片重分配控制避免数据迁移

下一步

配置完成后,我们就可以开始创建快照了。但这个过程又带来了新的挑战,详见下一篇博客。