首页
/ Milvus 源码构建实战:用 update-milvus-api 一键升级 milvus-proto 依赖版本

Milvus 源码构建实战:用 update-milvus-api 一键升级 milvus-proto 依赖版本

2026-09-05 13:54:36作者:庞队千Virginia

Milvus 采用“主仓库 + 独立 proto 仓库(milvus-proto)”的依赖结构,API 接口的每一次演进都需要同步更新 go-api Go 模块版本与本地第三份 proto 仓库。本文基于 UPDATE_MILVUS_API.mdscripts/update-api-version.sh 的源码实现,详解 make update-milvus-api 命令的工作原理、两种版本号用法(tag / commit ID)、涉及的 4 个 go.mod 文件,以及它与 Milvus 整体构建链路(下载 proto、生成代码)的衔接关系,读完即可在 Milvus 二次开发中安全、可重复地升级 API 依赖。

一、milvus-proto 在 Milvus 中的双重角色

在动手执行命令之前,先理解为什么要单独管理 milvus-proto,这决定了该命令必须“多路同步更新”:

1. 作为 Go 依赖(go-api 模块)。Milvus 仓库拆分为 4 个 Go 模块,它们各自依赖独立的 go-api 模块:

Go 模块 go.mod 位置 说明
主模块 go.mod 服务端各组件(rootcoord、querynode 等 internal 包)
client 模块 client/go.mod 对外发布的 Go SDK(milvusclient 包)
pkg 模块 pkg/go.mod 公共基础库(util、mlog、mq 等)
测试 client 模块 tests/go_client/go.mod Go 客户端集成测试

当前仓库 4 个 go.mod 中该依赖均锁定为同一版本(如 github.com/milvus-io/milvus-proto/go-api/v3 v3.0.0-20260806081414-16b288837fbd),这正是本文命令要保证的一致性目标。client SDK 大量直接使用这些生成代码,例如 client/milvusclient/read_options.go 导入 go-api/v3/commonpbgo-api/v3/milvuspb 包来构造 gRPC 请求。

2. 作为 C++/Go 代码生成的 proto 源文件。构建 Milvus 时,scripts/generate_proto.sh 会设置 API_PROTO_DIR=$ROOT_DIR/cmake_build/thirdparty/milvus-proto/proto,将其作为 protoc --proto_path 的一部分,配合本仓库 pkg/proto 下的 proxy.protoroot_coord.proto 等内部协议文件一起生成 *pb 包。也就是说,升级 milvus-proto 不只影响 Go 编译,还影响 protoc 生成产物——这就是为什么升级命令除了 go get,还要更新 cmake_build/thirdparty 下的本地 milvus-proto 仓库。

二、命令入口与执行流程

命令入口在 Makefile 中定义:

update-milvus-api: download-milvus-proto
	@echo "Update milvus/api version ..."
	@(env bash $(PWD)/scripts/update-api-version.sh $(PROTO_API_VERSION))

download-milvus-proto:
	@echo "Download milvus-proto repo ..."
	@(env bash $(PWD)/scripts/download_milvus_proto.sh)

注意两个细节:

  1. update-milvus-api 依赖 download-milvus-proto 前置目标,会先执行 scripts/download_milvus_proto.sh:若 cmake_build/thirdparty/milvus-proto 不存在则 git clone,然后 git fetch --tags 并按 go.mod 中已记录的版本(tag 或从 pseudo-version 解析出的 commit)执行 git reset --hard,保证本地 proto 仓库与依赖版本一致;
  2. 真正的版本号升级逻辑在 scripts/update-api-version.sh 中。

从源码看,脚本的执行流程与文档描述的 5 个步骤一一对应:

① 版本校验     git ls-remote <milvus-proto 仓库> refs/tags/${version}
               有输出 → 是合法 tag;无输出 → 视为 commit ID
② 更新 4 个 go.mod(主/client/pkg/tests/go_client)
               每个模块依次执行:
               go get -u github.com/milvus-io/milvus-proto/go-api/v3@$update_version
               go mod tidy
③ 清理构建产物中可能受污染的目录
               rm -rf cmake_build/thirdparty/protobuf/protobuf-src/examples
④ 更新本地 milvus-proto 仓库
               pushd cmake_build/thirdparty/milvus-proto
               git fetch
               git checkout -b $version $commitID 2>/dev/null || git checkout $commitID
               popd
⑤ 输出结果     打印成功信息及被更新的 4 个 go.mod 文件列表

其中第 ④ 步的 git checkout -b ... || git checkout ... 正是文档中“若同名 git 分支已存在,则直接 checkout commit”这一错误处理策略的实现:先尝试以版本号命名新分支指向目标 commit,若分支已存在则退化为直接切换到 commit。

三、两种版本号用法

1. 更新到已打 tag 的版本

make update-milvus-api PROTO_API_VERSION=v2.3.0-dev.1

脚本通过 git ls-remote 确认该 tag 在 milvus-proto 远端真实存在,并以 tag 名作为 go get 的版本参数,四个 go.mod 会解析为 Go 模块的语义化版本。

2. 更新到未打 tag 的 commit ID

make update-milvus-api PROTO_API_VERSION=4080770055ad

git ls-remote 查无此 tag 时,脚本打印提示 not a valid tag, try to use it as commit ID,并把该值直接作为 commit ID 使用。此时 go.mod 中记录的是 Go 的 pseudo-version(形如 vX.Y.Z-时间戳-commit短哈希),而本地 milvus-proto 仓库会 checkout 到该 commit。这种用法是 proto 仓库与 Milvus 主仓库并行开发(API 尚未合入打 tag)时的标准升级路径。

成功输出示例

命令执行后输出类似(引自文档,并对应脚本中的 echo 语句):

----------------------------
Update the milvus-proto/go-api/v2@v2.3.0-dev.1
Updating milvus-proto version in all go.mod files...
Updating main go.mod...
Updating client/go.mod...
Updating pkg/go.mod...
Updating tests/go_client/go.mod...
----------------------------
Update the milvus-proto repo
----------------------------
Successfully updated milvus-proto version to v2.3.0-dev.1 in all go.mod files:
  - go.mod
  - client/go.mod
  - pkg/go.mod
  - tests/go_client/go.mod

提示:文档中的示例输出沿用 go-api/v2 措辞;当前脚本实际执行的是 go get -u github.com/milvus-io/milvus-proto/go-api/v3@$update_version(见 scripts/update-api-version.sh 第 41、47、53、59 行),即仓库已迁移到 go-api 的 v3 major 版本,使用时请以脚本与 go.mod 实际内容为准。

四、错误处理与前置条件

前置条件(Prerequisites)

  • gogit 均已安装并在 PATH 中可用(脚本全程依赖 go getgo mod tidygit ls-remote/git fetch);
  • 需要网络访问,以便拉取 milvus-proto 远端的 tag/commit 元信息,以及 download-milvus-proto 阶段的 clone/fetch。

错误处理策略

文档列出三条策略,均可在 scripts/update-api-version.sh 中逐条印证:

  1. 未提供版本号version 为空时,脚本打印两条用法示例(tag 方式与 commitID 方式)后 exit 1,属于快速失败,避免误跑空版本;
  2. 本地 milvus-proto 目录不存在cmake_build/thirdparty/milvus-proto 缺失时仅打印 Warning: milvus-proto directory not found ...,四个 go.mod 的更新不受影响并继续完成——即 proto 源码仓库与 Go 依赖的更新是解耦的;
  3. 同名分支已存在git checkout -b $version $commitID 失败时回退到 git checkout $commitID,保证命令幂等、可重复执行。

五、与构建链路的衔接:升级之后该做什么

update-milvus-api 解决的是“依赖版本同步”,而要真正让新 API 生效,还需注意它在整个构建体系中的位置:

  • 后续执行 make generated-proto / make build-cpp 时,protoc 的输入来自 cmake_build/thirdparty/milvus-proto/proto(见 scripts/generate_proto.shAPI_PROTO_DIR 的定义)。如果只跑了 go get 而没有同步本地 proto 仓库,可能出现 Go 侧 go-api 代码与 C++ 侧 .proto 定义不一致的隐患;
  • make check-proto-product 依赖 generated-proto,可用来校验生成产物是否符合预期(scripts/check_proto_product.sh);
  • 日常流程建议为:make update-milvus-api PROTO_API_VERSION=<tag 或 commitID>make generated-protomake check-proto-product,最后按 Makefile 常规流程编译验证。

六、小结

  • update-milvus-api 是 Milvus 维护 API 依赖一致性的专用工具:一次命令同时更新 go.modclient/go.modpkg/go.modtests/go_client/go.mod 四个模块中的 go-api 版本,并同步 cmake_build/thirdparty/milvus-proto 本地仓库;
  • 版本参数兼容两种形态:合法 git tag(vX.Y.Z 形式)与未打 tag 的 commit ID,脚本用 git ls-remote 自动判别;
  • 命令具备幂等性与降级容错:缺版本参数快速失败、缺本地 proto 目录降级为警告、分支冲突自动回退 commit 切换;
  • 升级后应衔接 generated-proto 等构建目标完成代码生成,并通过 check-proto-product 验证产物,确保 Go SDK、服务端 gRPC 接口与 C++ 侧 proto 定义三方一致。
登录后查看全文
热门项目推荐
相关项目推荐