news 2026/9/10 15:34:46

Milvus 滚动升级自动化测试实战指南:基于 Kubernetes CRD 的无中断升级验证方案

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Milvus 滚动升级自动化测试实战指南:基于 Kubernetes CRD 的无中断升级验证方案

Milvus 滚动升级自动化测试实战指南:基于 Kubernetes CRD 的无中断升级验证方案

【免费下载链接】milvusMilvus is a high-performance, cloud-native vector database built for scalable vector ANN search项目地址: https://gitcode.com/GitHub_Trending/mi/milvus

本文以 Milvus 开源仓库中tests/python_client/rolling_upgrade目录下的滚动升级测试体系为主线,系统讲解 Milvus 在 Kubernetes 环境下通过 Milvus Operator CRD 完成无中断版本升级的验证方案:从默认整集群升级、组件逐一手动升级,到升级期间并发/单类请求压测、成功率与 RTO 指标断言,以及 Pod 状态监控与 parquet 结果归档。读完本文,你将掌握这套测试套件的完整用法、每个命令行参数的默认值与语义、底层 kubectl patch 与 Python 探针的实现原理,以及如何在自己的集群上复现"升级不中断业务"的验收流程。

一、为什么需要滚动升级测试

Milvus 是云原生向量数据库,集群由 proxy、rootCoord、dataCoord、indexCoord、queryCoord、dataNode、queryNode、indexNode 等多个无状态/有状态组件组成。在生产环境中升级版本时,若直接删除重建全部 Pod,会造成服务中断和数据读写失败。

滚动升级(Rolling Upgrade)的目标是:在保持服务持续可用(Continuous service availability)的前提下,逐批替换组件镜像,同时保证:

  • 数据完整性(Data integrity):升级过程中写入的数据不丢失、不损坏;
  • 性能影响最小化(Minimal performance impact):请求成功率与恢复时间(RTO)维持在可接受范围;
  • 客户端操作兼容(Client operation compatibility):升级前后客户端 API 行为一致,insert/search/query/delete 等操作不报错。

仓库在 tests/python_client/rolling_upgrade/README.md 中对这套测试体系给出了整体说明,本文后续章节将逐层展开。

二、测试套件全景:目录结构与职责划分

整个滚动升级测试套件位于 tests/python_client/rolling_upgrade,共 6 个 Python 文件 + 2 个 CRD 配置:

文件类别职责
test_rolling_update_by_default.py核心测试默认滚动升级:通过 CRD 一次性更新所有组件镜像
test_rolling_update_one_by_one.py核心测试逐组件升级:按序逐个 patch 各组件镜像并等待就绪
testcases/test_concurrent_request_operation_for_rolling_update.py操作测试升级期间并发压测 insert/search/query/delete
testcases/test_single_request_operation_for_rolling_update.py操作测试升级期间单类操作测试(含 create/flush/index)
monitor_rolling_update.py工具独立的 Pod 状态轮询监控脚本
conftest.py配置pytest 命令行参数注册与 fixture
milvus_crd/milvus_crd.yamlCRD标准集群部署配置(cluster 模式)
milvus_crd/milvus_mixcoord_crd.yamlCRDMixCoord 合并协调器部署配置

2.1 默认滚动升级测试

test_rolling_update_by_default.py 中test_operations的核心流程:

  1. 读取milvus_crd.yaml,将spec.components.image设置为目标镜像{new_image_repo}:{new_image_tag}
  2. spec.components.imageUpdateMode设置为rollingUpgrade(默认升级模式,由 Milvus Operator 接管滚动替换);
  3. 清空各子组件(indexNode、rootCoord、dataCoord、indexCoord、queryCoord、dataNode、queryNode、proxy、standalone、mixCoord)中残留的image字段,确保统一走顶层镜像;
  4. 通过kubectl patch <kind> <name> --patch-file milvus_crd_modified.yaml --type merge提交变更;
  5. 轮询kubectl get podkubectl get mi <name>,直到 Milvus 自定义资源状态中出现True(Ready),判定升级完成。

该用例标注为@pytest.mark.tags(CaseLabel.L3),属于 L3 级别的系统级验证。

2.2 逐组件升级测试

test_rolling_update_one_by_one.py 支持更精细的控制,其默认升级顺序为:

['indexNode', 'rootCoord', ['dataCoord', 'indexCoord'], 'queryCoord', 'queryNode', 'dataNode', 'proxy']

其中['dataCoord', 'indexCoord']表示这两个组件在同一批次内同时更新。执行时,测试对每个组件单独 patch 镜像并等待集群恢复健康,等待逻辑包括:

  • 每 10 秒轮询kubectl get mi,要求输出同时包含TrueHealthy
  • 健康状态需连续稳定 1 分钟(每 10 秒检查一次、共 6 次)才视为通过;
  • queryNode额外调用check_querynode_upgrade_complete:确认旧的 queryNode Deployment 已缩到 0/0、新的 Deployment 已满副本 Ready,才认为升级彻底完成。

文件同时提供pause_and_resume_rolling函数,通过向 CRD patchspec.components.paused: true/false实现暂停/恢复指定 Deployment 的滚动更新,并支持传入updated_pod_count(更新多少个副本后暂停)与pause_seconds(暂停秒数),用于模拟升级中途停顿场景。

三、关键配置参数详解

3.1 命令行参数(conftest.py)

所有核心参数均在 conftest.py 中通过pytest_addoption注册,并通过同名 fixture 注入测试:

参数类型默认值语义
--release_namestrdeploy-test部署测试使用的 Helm release 名
--new_image_repostrharbor.milvus.io/dockerhub/milvusdb/milvus目标镜像仓库
--new_image_tagstrmaster-20231031-ab6dbf76目标版本 tag
--components_orderstr['indexNode', 'rootCoord', ['dataCoord', 'indexCoord'], 'queryCoord', 'queryNode', 'dataNode', 'proxy']组件更新顺序(字符串形式传入,测试内eval解析)
--paused_componentsstr['queryNode']升级期间需要暂停的组件列表
--paused_durationint300暂停时长(秒)
--prepare_databoolFalse是否通过 bulk insert 预写数据

此外,操作类测试依赖的--request_duration(压测持续时间,默认 1800 秒)与--is_check(是否强制执行成功率断言,默认 True)由更上层的 pytest 配置注册,例如 tests/python_client/cdc/conftest.py 中的request_duration/is_checkfixture 就展示了这类参数的注册与 bool 兼容处理方式。

注意:--request_duration支持30m1h30m这类人类可读写法,测试内部会通过字符串替换(h→*3600+m→*60+、去掉s)后eval换算为秒。

3.2 CRD 关键字段(milvus_crd.yaml)

master CRD 示例(apiVersionmilvus.io/v1beta1,kindMilvus)中与滚动升级直接相关的字段:

spec: mode: cluster components: enableRollingUpdate: true # 开启 Operator 的滚动更新能力 imageUpdateMode: rollingUpgrade # 镜像更新模式:rollingUpgrade / all / rollingRestart image: milvusdb/milvus:2.2.0-20231021-1f972292 # 当前运行版本 proxy: replicas: 1 dataNode: replicas: 3 indexNode: replicas: 3 queryNode: replicas: 3 resources: requests: { cpu: 2, memory: 8Gi } limits: { cpu: 4, memory: 16Gi } dependencies: msgStreamType: kafka # 消息流中间件类型 etcd: inCluster: deletionPolicy: Retain storage: type: Azure inCluster: deletionPolicy: Retain

示例还展示了enableActiveStandby: true(rootCoord/dataCoord/queryCoord/indexCoord 均启用主备)与quotaAndLimits.enable: false(关闭配额限制以便压力测试充分放量)、log.level: debug等辅助配置。dependencies 部分配置了 inCluster 的 etcd(3 副本)、kafka(3 副本)以及可选的 pulsar、Azure 存储(deletionPolicy: Retain保证升级期间元数据与对象存储不丢失)。

混部 MixCoord 版本则在 components 中以单个mixCoord组件(replicas: 1)取代了分散的 rootCoord/dataCoord/queryCoord/indexCoord,适合验证 MixCoord 架构下的升级路径,并额外演示了podAnnotations(pyroscope 性能剖析注解)等字段。

四、运行测试

4.1 前置条件

  1. 一个已安装Milvus Operator的 Kubernetes 集群;
  2. kubectl已配置好集群访问权限(测试通过kubectlCLI 与 Kubernetes Python SDK 操作资源);
  3. Python 环境已安装 pytest、pymilvus、kubernetes、pandas、PyYAML、loguru 等依赖(套件位于 tests/python_client 体系内,复用其common/utils/chaos等公共模块)。

4.2 基本用法

# 运行默认滚动升级测试(一次性更新全部组件) pytest test_rolling_update_by_default.py -v # 运行逐组件升级测试 pytest test_rolling_update_one_by_one.py -v # 自定义参数:换目标镜像、暂停 queryNode 600 秒 pytest test_rolling_update_one_by_one.py \ --new_image_repo=milvusdb/milvus \ --new_image_tag=v2.4.1 \ --paused_components=queryNode \ --paused_duration=600 # 升级期间并发压测(持续 30 分钟,强制断言) pytest testcases/test_concurrent_request_operation_for_rolling_update.py \ --request_duration=30m --is_check=true # 升级期间单类操作测试 pytest testcases/test_single_request_operation_for_rolling_update.py \ --request_duration=1800

升级操作测试文件还依赖--host(默认 127.0.0.1)、--port(默认 19530)、--user/--password--minio_host等连接参数,用于建立指向被测集群的 pymilvus 连接。

4.3 监控 Pod 状态

独立的监控脚本 monitor_rolling_update.py 会在指定时长内以固定间隔反复执行kubectl get pod | grep <release_name>并输出日志:

# 监控 10 分钟,每 5 秒采样一次,过滤 release 名 my-release python monitor_rolling_update.py --duration 600 --interval 5 --release my-release

参数:-d/--duration(默认 600 秒)、-i/--interval(默认 5 秒)、-n/--release_name。该脚本常与升级测试并行运行,用于留存升级过程中 Pod 重建、ContainerCreating、Running 等状态的完整时间线。

五、成功标准(Success Criteria)

5.1 升级期间

  • 成功率(Success Rate):所有操作的成功率 ≥ 98%;
  • RTO:每类操作的恢复时间(Recovery Time Objective)≤ 10 秒;
  • Pod 状态:所有 Pod 最终达到 Ready。

5.2 升级完成后

  • 成功率:所有操作成功率 100%;
  • 集群健康:所有组件健康;
  • 数据完整性:无数据丢失或损坏。

这些标准并非只是文档描述,而是硬编码在测试断言中。以 test_concurrent_request_operation_for_rolling_update.py 为例:

if is_check: assert_statistic(self.health_checkers, succ_rate_threshold=0.98) # 升级期间 ≥98% for k, v in self.health_checkers.items(): rto = v.get_rto() pytest.assume(rto <= 10, f"{k} rto expect 10s but get {rto}s") # RTO ≤ 10s ... assert_statistic(self.health_checkers, succ_rate_threshold=1.0) # 升级后 100%

同时,测试在升级完成后会通过wait_pods_ready("chaos-testing", label_selector)等待所有 Pod 就绪,并再压测 120 秒确认成功率回到 100%,覆盖"升级后集群恢复"这一阶段。

六、测试结果归档

两类操作测试都会将结果以parquet 格式保存到/tmp/ci_logs/下,便于 CI 收集与分析:

  • 并发测试:/tmp/ci_logs/concurrent_request_result.parquet
  • 单类测试:/tmp/ci_logs/single_request_result.parquet

每条记录包含字段:op(操作类型)、failed request ts(失败请求时间戳列表)、failed request order(失败请求序号列表)、rto(该类操作的恢复时间)。文件在测试中通过 pandasdf.to_parquet()生成。

七、底层原理:从测试看滚动升级如何工作

7.1 升级过程架构

Rolling Upgrade Process: ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ Old Image │ --> │ Upgrading │ --> │ New Image │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ │ v v v [Running Pods] [Mixed Pods] [Updated Pods] │ │ │ └────────────────────┴────────────────────┘ Continuous Operations

升级过程经历"旧镜像 Pod 全量运行 → 新旧 Pod 混合共存 → 新镜像 Pod 全量接管"三个阶段,期间业务请求持续打到集群上(由测试的 monitor checker 线程持续发起),这正是验证滚动升级"无中断"的关键。

7.2 两种升级策略的实现差异

从两个测试文件的源码可以清晰看到策略差异:

  • 默认测试(rollingUpgrade 模式):只 patch 顶层spec.components.imageimageUpdateMode: rollingUpgrade,由Milvus Operator统一编排所有组件的滚动替换顺序;
  • 逐组件测试(all 模式):先删除顶层 image,设置imageUpdateMode: all,再按components_order逐个组件 patch 各自image字段,每次 patch 后都等待集群健康稳定,实现对升级顺序、停顿(paused)的完全手工控制。

7.3 健康探针与稳定性判定

逐组件测试对"就绪"的判定非常严格:不仅要求kubectl get mi输出包含TrueHealthy,还要求该状态连续保持 60 秒(6 次 × 10 秒采样)不波动;对 queryNode 这种数据面核心组件,还需额外确认旧 Deployment 副本完全归零。这种"稳定窗口 + 双状态检查"的设计,能有效避免升级中途的抖动被误判为成功。

7.4 操作检查器(Checker)机制

操作测试依赖chaos.checker模块的检查器类。单类测试注册了 7 类检查器:

checkers = { Op.create: CollectionCreateChecker(collection_name=None, schema=schema), Op.insert: InsertChecker(collection_name=c_name, schema=schema), Op.flush: FlushChecker(collection_name=c_name, schema=schema), Op.index: IndexCreateChecker(collection_name=None, schema=schema), Op.search: SearchChecker(collection_name=c_name, schema=schema), Op.query: QueryChecker(collection_name=c_name, schema=schema), Op.delete: DeleteChecker(collection_name=c_name, schema=schema), }

并发测试则聚焦 insert/search/query/delete 四类高频操作(bulk_insert检查器被注释保留,便于按需启用)。测试通过cc.start_monitor_threads(health_checkers)启动各检查器的监控线程,在request_duration内持续施压,期间每duration // 10秒调用一次check_result()汇总失败记录,结束后调用pause()停止并读取fail_recordsget_rto()

八、实战建议

  1. 先跑单类测试再跑并发测试:单类测试覆盖 create/flush/index 等 DDL 类操作,能更早暴露升级对元数据面的影响;并发测试更贴近真实负载。
  2. 合理设置--paused_duration:默认 300 秒。若需验证长暂停场景下客户端连接保持与重试机制,可适当加大(如 600 秒)。
  3. 组合使用监控脚本:升级期间并行运行monitor_rolling_update.py,可留存 Pod 重建时序,便于失败时回溯是哪个组件、哪个阶段出现问题。
  4. 利用 parquet 结果定位瓶颈failed request tsrto字段可直接用于分析失败请求是否集中在某组件替换窗口,从而判断是否需要调整components_order
  5. 注意 CRD 与脚本的路径约定:套件运行时默认读取 CRD 文件并生成milvus_crd_modified.yaml临时 patch 文件(默认生成在测试文件同目录),提交到 CI 前请确认该目录可写,且kubectl所在 namespace 与 CRD 中metadata.namespace(示例为chaos-testing)一致。

九、小结

Milvus 的滚动升级测试体系提供了一条从"升级编排"到"业务验证"的完整闭环:通过milvus.io/v1beta1CRD 与kubectl patch驱动 Operator 完成整集群或逐组件的镜像替换,通过基于 pymilvus 的 checker 线程在升级窗口内持续压测并断言 ≥98% 成功率与 ≤10s RTO,最后以 parquet 形式归档结果。这套方案既可作为 Milvus 版本发布前的质量门槛,也可直接借鉴到任何基于 Kubernetes Operator 的分布式系统升级验收中。

【免费下载链接】milvusMilvus is a high-performance, cloud-native vector database built for scalable vector ANN search项目地址: https://gitcode.com/GitHub_Trending/mi/milvus

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/10 15:31:08

微电网多目标优化调度:MOPSO算法与MATLAB实践

1. 项目概述&#xff1a;微电网调度优化的现实挑战 微电网作为分布式能源系统的核心载体&#xff0c;正在全球范围内加速普及。我在参与某工业园区微电网项目时&#xff0c;深刻体会到传统调度方法的局限性——当光伏出力突然波动30%时&#xff0c;单纯追求经济性的调度策略会导…

作者头像 李华
网站建设 2026/9/10 15:30:48

基于Node.js的电商购物商城系统毕业设计实战指南

简介&#xff1a;基于Node.js Express框架的电商购物商城系统毕业设计源码&#xff0c;适合Node.js入门学习者、中小型Web项目开发者&#xff0c;以及正在准备电商类课程设计的高校学生。项目围绕前台购物页面与后台服务逻辑展开&#xff0c;包含数据库操作示例和详细注解&…

作者头像 李华
网站建设 2026/9/10 15:28:56

Polars自定义函数性能优化与实战技巧

1. Polars与Python自定义函数深度实践指南 在数据处理领域&#xff0c;Polars正以惊人的速度成为替代Pandas的新选择。这个基于Rust构建的高性能DataFrame库&#xff0c;在处理GB级别数据时仍能保持毫秒级响应。但很多从Pandas迁移过来的开发者&#xff0c;在使用自定义函数(UD…

作者头像 李华