You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

生产环境:为运行中Elasticsearch容器挂载卷且避免数据丢失

生产环境Elasticsearch容器挂载卷的低停机迁移方案

问题背景

通过docker-compose部署的Elasticsearch+Kibana,ES容器已运行许久,存储约600GB数据,但未挂载数据卷。重启容器或修改配置会导致数据丢失,需在仅允许极短停机时间的生产环境下,完成数据到卷的迁移,且避免数据丢失。

之前尝试的两种方法均不满足要求:

  • docker commit:创建镜像耗时极长(600GB需400-600分钟),操作期间新写入的数据无法同步
  • docker cp:复制过程耗时久,且复制期间产生的增量数据会丢失,停机窗口过长

核心痛点:操作全程的增量数据无法留存,整体耗时不符合生产环境要求。


最优方案:ES集群滚动迁移+容器卷挂载

利用Elasticsearch原生的集群分片同步特性,实现几乎无停机的数据迁移,同时保证数据完整性。

前置条件

  • 有额外服务器资源可临时启动同版本ES容器
  • 新旧ES节点版本、集群配置(集群名、网络)完全一致
  • 已做好全量数据备份(如使用elasticsearch-snapshot)

具体操作步骤

1. 启动挂载数据卷的新ES节点

修改现有docker-compose.yml,新增一个配置好数据卷的ES服务:

services:
  # 原ES节点(保留,后续停用)
  es-old:
    image: elasticsearch:<你的ES版本>
    environment:
      - cluster.name=your-cluster-name
      - node.name=es-old
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms4g -Xmx4g"
    networks:
      - es-network
    ulimits:
      memlock:
        soft: -1
        hard: -1

  # 新增挂载数据卷的ES节点
  es-new:
    image: elasticsearch:<你的ES版本>
    volumes:
      - es-data:/usr/share/elasticsearch/data  # 挂载持久化卷
    environment:
      - cluster.name=your-cluster-name
      - discovery.seed_hosts=es-old  # 指向原节点服务名/IP
      - node.name=es-new
      - bootstrap.memory_lock=true
      - "ES_JAVA_OPTS=-Xms4g -Xmx4g"
    networks:
      - es-network
    ulimits:
      memlock:
        soft: -1
        hard: -1

volumes:
  es-data:
    driver: local

networks:
  es-network:
    external: false

启动新节点:

docker-compose up -d es-new

2. 等待集群数据同步完成

通过Kibana Dev Tools执行命令,查看分片同步状态:

GET _cat/shards?v

当所有分片的STATE显示为STARTED,且新节点拥有对应分片副本时,同步完成。

3. 锁定原节点写入,处理最后增量

为确保同步完成后无新数据写入原节点,将原ES设置为只读:

PUT /_all/_settings
{
  "index.blocks.write": true
}

等待1-2分钟,确认所有正在处理的写入请求完成,此时新节点已同步所有数据(含最后增量)。

4. 切换流量到新节点(极短停机)

停止原ES节点:

docker-compose stop es-old

修改docker-compose.yml,将新节点的服务名改为原ES的服务名(如es),确保Kibana等依赖服务指向正确,然后重启相关服务:

# 修改后启动新节点(替换原服务名)
docker-compose up -d es
# 重启Kibana以更新ES地址
docker-compose restart kibana

5. 恢复ES可写状态

执行命令解除只读限制:

PUT /_all/_settings
{
  "index.blocks.write": null
}

6. 清理临时资源(可选)

确认新节点运行正常、数据完整后,删除原ES容器及临时配置。

方案优势

  • 停机窗口极小:仅切换流量的1-2分钟内不可写,远低于传统方法的数小时
  • 数据零丢失:通过ES集群同步保证全量+增量数据完整
  • 操作可控:依赖ES原生特性,无需Docker层面的慢复制操作

备选方案(无额外资源时)

如果无法新增节点,可采用直接迁移容器数据目录到卷的方式,停机窗口等于数据复制时间:

  1. 查找原ES容器的主机数据目录:
docker inspect <原ES容器ID> | grep -A 5 "Source" | grep "/var/lib/docker/volumes/" | awk '{print $2}' | sed 's/\"//g'
  1. 停止ES容器(开始停机):
docker-compose stop es
  1. 创建新卷并复制数据:
docker volume create es-data
docker run --rm -v <步骤1得到的目录>:/old-data -v es-data:/new-data busybox cp -a /old-data/. /new-data/
  1. 修改docker-compose.yml挂载新卷,启动ES:
docker-compose up -d es

内容的提问来源于stack exchange,提问作者KKI

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 08:24:59