[milvus-backup]milvus-standalone跨服务器迁移

[milvus-backup] Milvus Standalone 跨服务器迁移完整记录

Milvus-Backup是一个允许用户备份和恢复Milvus数据的工具。Milvus备份过程对Milvus的性能影响可忽略不计。在备份和恢复过程中,Milvus集群仍完全正常运行。一般应用于对象存储的Milvus数据,现也支持本地存储的Milvus数据迁移。本文使用 milvus-backup 工具将 Milvus Standalone(local 存储)完整迁移到目标服务器,含踩坑实录。

适用场景:源服务器 Milvus 使用 common.storageType: local,数据存储在本地磁盘。需要完整迁移数据(含索引)到新服务器。

环境

  • milvus-backup 0.5.16
  • 源 Milvus:2.5.6 → 目标 Milvus:2.5.8
  • CPU 架构:arm64

整体流程

前置准备(磁盘/架构/挂载路径/工具准备)
  → 源服务器备份(配置 → 备份 → 传输) local → local
  → 目标服务器部署(启动 Milvus → 恢复备份)local → local
  → 验证

一、前置准备

开始迁移前,需要先确认磁盘空间、CPU 架构、当前 Milvus 的存储配置,并提前下载好备份工具。

1.1 磁盘空间评估

查看源服务器剩余存储空间和相应的milvus容器数据存储量, 确保目标服务器剩余存储空间足够

# 数据盘所在分区磁盘使用情况,重点看 Avail(剩余)和 Use%
df -h /path/to/

# Docker 数据根目录
docker info | grep "Docker Root Dir"

# 指定目录所在分区
df -hT $(docker info --format '{{.DockerRootDir}}')

设源数据量为 S,目标可用空间为 A

  • 仅恢复:A ≥ S × 1.2(预留 20%)
  • 保留压缩包再解压:A ≥ S × 2.2

1.2 CPU 架构确认和备份工具下载

# 确认 CPU 架构,选择对应版本
uname -m

输出示例:aarch64(arm64)或 x86_64

根据架构下载对应版本的 milvus-backup,有两种使用方式:

推荐直接用容器镜像,镜像已包含所有依赖,且无需关心架构匹配问题。

# 方式一:直接拉取容器镜像(推荐)
docker pull milvusdb/milvus-backup:latest

# 方式二:下载二进制(需手动匹配架构)
# 从 GitHub Releases 选择对应架构的压缩包
# https://github.com/zilliztech/milvus-backup/releases
wget https://github.com/zilliztech/milvus-backup/releases/download/v0.5.16/milvus-backup_0.5.16_Linux_arm64.tar.gz
tar -zxvf milvus-backup_0.5.16_Linux_arm64.tar.gz

两种方式的区别:

方式 优点 缺点
容器镜像 免架构匹配,开箱即用 需要 Docker 环境
二进制 轻量,可直接在宿主机运行 需手动匹配架构,依赖 glibc 版本

配置文件模板官方 backup.yaml — 内容较多,local 模式只需关注 milvusminio 配置段

1.3 查看 Milvus 容器挂载与存储配置

# 找到 Milvus 容器
docker ps -a | grep -i milvus

# 进入容器确认bucketName
docker exec -it <milvus-container-name> bash
cat /milvus/configs/milvus.yaml | grep -E "bucketName|rootPath"

# 查看数据卷挂载
docker inspect <容器名> --format '{{range .Mounts}}{{.Source}} -> {{.Destination}}{{println}}{{end}}'

数据卷挂载输出示例:

/data/mymilvus/volumes/milvus -> /var/lib/milvus
/data/mymilvus/embedEtcd.yaml -> /milvus/configs/embedEtcd.yaml
/data/mymilvus/user.yaml -> /milvus/configs/user.yaml

二、源服务器:执行备份

2.1 配置 backup.yaml(核心)

核心需要修改 milvusminio 配置段:

milvus:
  address: localhost
  port: 19530        # 与实际 Milvus 容器端口一致
  user: "root"
  password: "Milvus"  # 用户根据实际密码修改

minio:
  # ─── 源 Milvus 存储配置(告诉 backup 去哪里读数据) ───
  storageType: "local"             # 必须与 milvus.yaml 中的 common.storageType 一致
  address: "localhost"             # local 模式下无实际意义
  port: 9000
  bucketName: "a-bucket"           # 从源 Milvus 的 milvus.yaml 中获取
  localPath: "/var/lib/milvus/data"     # 数据的实际路径,使用容器的话,要写容器内的路径(与 docker -v 挂载的容器路径对应)
  rootPath: "/var/lib/milvus/data"      # 与上面保持一致

  # ─── 备份输出存储配置(备份文件写到哪里) ───
  backupStorageType: "local"
  backupBucketName: "a-bucket"     # local 模式下保留与 bucketName 一致
  backupRootPath: "/backup_data"   # 备份文件的存储路径,若使用容器,应写在容器内的输出目录
  backupLocalPath: "/backup_data"  # 备份文件的存储路径,若使用容器,应写在容器内的输出目录
  crossStorage: "false"            # local→local 保持 false

除此之外的 S3/MinIO 密钥等参数可注释,local 模式不需要。

⚠️ 踩坑:rootPath/localPath配置

写好配置后,备份过程会出现各种报错,以下是逐级排查经验:

报错 1:运行 ./milvus-backup check时候出现!!! Milvus root path is empty !!!

  • 原因rootPath 配置错误,备份工具找不到数据目录
  • 排查要点
    1. 容器内运行备份工具时,rootPath 必须与 容器内路径 对应(不是宿主机路径)
    2. 确认 -v 挂载的宿主机目录下确实有数据

报错 2:segment X has no insert logs

网上多数说法是指路径不对应,但经过反复验证:

  • 问题的真实原因是:Milvus 2.5.x 特定版本的 bug
  • rootPath 需要指向 insert_log 文件夹的父目录(以 2.5.6 为例,数据路径是 volumes/milvus/datarootPath应填/path/to/volumes/milvus/data,即数据目录的父级。之前一直填的是/path/to/volumes/milvus
    fd4d1e6a52fa0196bbe85eb71505bf01

报错 3:Failed to back up RPC channel position(WARN 级别)

  • 结论可忽略,仅影响 CDC 增量同步,完整备份不受影响

b6e7f180715bb2b48a9dc446b0498788

报错 4:备份后找不到备份文件

  • 原因backupLocalPath 没有在 docker run 时用 -v 映射出去
  • 解决:容器启动时加上 -v /宿主机目录:/backup_data

各字段取值来源速查

backup.yaml 字段 值来源 说明
storageType milvus.yaml →common.storageType 必须一致
bucketName milvus.yaml →minio.bucketName
rootPath -v 挂载的容器内路径 通常为/var/lib/milvus/data
backupRootPath -v 挂载的容器内路径 推荐/backup_data,手动创建
crossStorage 源→目标是否跨类型 local→local =false

2.3 执行备份

# 创建宿主机备份目录
mkdir -p /data/mymilvus/backup_data

# 启动 backup 容器
docker run -itd \
    --network host \
    --name milvus_backup_src \
    -v /path/to/backup.yaml:/app/backup.yaml \
    -v /data/mymilvus/volumes/milvus:/var/lib/milvus \
    -v /data/mymilvus/backup_data:/backup_data \
    milvusdb/milvus-backup:latest \
    sleep infinity

# 进入容器执行备份
docker exec -it milvus_backup_src /bin/sh

# 检查数据目录是否正常
./milvus-backup check  # 指定配置:--config /path/backup.yaml

# 创建备份(全量)
./milvus-backup create -n fullbackup

补充 create 常用参数:

参数 说明
-n, --name 备份名称,恢复时需要用这个名字指定
--filter 按 collection 筛选备份,格式为 数据库名.集合名,例如 --filtermy_db.my_collection,支持 * 通配。如 --filter "my_db.*" 只备份指定库
--backup_index_extra 是否备份索引的额外信息

示例:只备份某个 collection

./milvus-backup create -n partial_backup --filter "my_db.my_collection"

看到 "finish backup" 后退出容器。

2.4 传输到目标服务器

tar -czvf milvus_backup_fullbackup.tar.gz /data/mymilvus/backup_data

传输方式参考:服务器间传文件


三、目标服务器:部署并恢复

3.1 先启动 Milvus 完成初始化

目标服务器需要先启动一次 Milvus 完成初始化(会在数据目录下创建 insert_log/stats_log/ 等子目录),然后才能 restore。

docker run -itd \
    --name mymilvus \
    --security-opt seccomp:unconfined \
    -e ETCD_USE_EMBED=true \
    -e ETCD_DATA_DIR=/var/lib/milvus/etcd \
    -e ETCD_CONFIG_PATH=/milvus/configs/embedEtcd.yaml \
    -e COMMON_STORAGETYPE=local \
    -e TZ=Asia/Shanghai \
    -v /etc/localtime:/etc/localtime:ro \
    -v /etc/timezone:/etc/timezone:ro \
    -v /data/mymilvus/volumes/milvus:/var/lib/milvus \
    -v /data/mymilvus/backup_data:/backup_data \
    -v /data/mymilvus/embedEtcd.yaml:/milvus/configs/embedEtcd.yaml \
    -v /data/mymilvus/user.yaml:/milvus/configs/user.yaml \
    -p 19530:19530 \
    --health-cmd="curl -f http://localhost:9091/healthz" \
    --health-interval=30s \
    --health-start-period=90s \
    --health-timeout=20s \
    --health-retries=3 \
    milvusdb/milvus:<目标版本> \
    milvus run standalone

等待健康检查通过(docker inspect mymilvus --format '{{.State.Health.Status}}' 返回 healthy)。

3.2 启动 backup 容器并恢复

docker run -itd \
    --network host \
    --name milvus_backup_task \
    -v /data/mymilvus/volumes/milvus:/var/lib/milvus \
    -v /data/mymilvus/backup_data:/backup_data \
    -v /path/to/backup.yaml:/app/backup.yaml \
    milvusdb/milvus-backup:latest \
    sleep infinity

# 进入容器
docker exec -it milvus_backup_task /bin/sh

# 查看备份列表确认
./milvus-backup list

# 执行恢复(含索引)
./milvus-backup restore -n fullbackup --restore_index=true

⚠️ 踩坑:恢复报错排查

报错 1:no binlog to import

这个报错让我卡了很久,完整排查路径如下:

  1. 路径不匹配backupRootPath-v 挂载的容器路径不一致

    • 检查:-v /host/backup_data:/backup_databackupRootPath 应为 /backup_data
    • 备份端的 backupRootPath 也必须一致,否则备份文件就写到了错误位置
  2. 缺少 backup_data 目录映射 → 目标服务器启动 Milvus 容器时加上 -v /data/mymilvus/backup_data:/backup_data,这个报错消失

  3. 存储访问权限 → Milvus 进程没有权限访问备份文件目录

报错 2:Missing field when appending row, got 114

通过排除了数据和路径问题后,查阅后备份文件夹的元数据信息(路径:./backup_data/meta/full_meta.json),发现第114个字段是sparse_vector(稀疏向量)字段,是milvus 内部使用bm25函数计算出来,属于 Milvus 2.5.6 的 bug

  • 升级到 2.6.x 版本后该问题消失
  • 但 2.6.x 与 2.5.x 的数据存放路径不同,导致数据导入一部分后无法恢复(升级跨度太大)
  • 最终方案:降到 2.5.8 版本,顺利恢复

结论:跨版本迁移时,目标版本与源版本差异不宜过大。建议尽量对齐 minor 版本号。


最终总结

关键注意事项

  1. 镜像版本尽量一致:源和目标 Milvus 版本差异不要太大(本文从 2.5.6 → 2.5.8 可行)
  2. 配置文件保持一致user.yamlembedEtcd.yaml 保持与源服务器一致
  3. backup.yaml 中的 rootPath:需指向数据目录的父级路径,且与 -v 挂载的容器路径对应
  4. backup_data 目录在两侧容器都要挂载:源端用于写备份,目标端用于读备份恢复

宝贵经验

  1. 多查官方文档,了解原理:不要完全依赖大模型回复,很多细节官方文档才有
  2. 善用工具辅助理解:利用 GitHub、deepwiki 等工具,快速理解原理和使用方法
  3. 从 GitHub Issue 中寻找线索:即使问题不完全一样,也可以通过蛛丝马迹找到解决思路
  4. 坚持不放弃:要亲眼确定事实,多尝试,多用脑思考。遇到报错不要慌,逐级排查根因

写在最后:这个方法对于本地存储的 Milvus 数据很麻烦做起来也不太划算,唯一好的一点就是不用关停milvus服务。在尝试的过程中获得了一些探索使用新工具的经验,也算不枉费力。

参考文档

posted @ 2026-07-03 15:43  第十昵称  阅读(0)  评论(0)    收藏  举报