🚀 免费试用 Zilliz Cloud,完全托管的 Milvus,体验 10 倍的性能提升!立即试用>

milvus-logo
LFAI
  • Home
  • Blog
  • 开放源码软件(OSS)质量保证 - Milvus 案例研究

开放源码软件(OSS)质量保证 - Milvus 案例研究

  • Engineering
April 25, 2022
Wenxing Zhu

Cover image 封面图片

本文由Wenxing Zhu撰写,Angela Ni 翻译。

质量保证(QA)是确定产品或服务是否符合特定要求的系统过程。质量保证系统是研发过程中不可或缺的一部分,因为顾名思义,它能确保产品的质量。

本篇文章将介绍开发 Milvus 向量数据库时采用的质量保证框架,旨在为作出贡献的开发人员和用户参与这一过程提供指导。文章还将介绍 Milvus 的主要测试模块,以及可用于提高质量保证测试效率的方法和工具。

跳转到

Milvus QA 系统简介

系统架构是进行质量保证测试的关键。质量保证工程师对系统越熟悉,就越有可能提出合理有效的测试计划。

Milvus architecture Milvus 架构

Milvus 2.0 采用云原生、分布式、分层架构,SDK 是 Milvus数据流动的主要入口。Milvus 用户使用 SDK 的频率非常高,因此非常需要对 SDK 进行功能测试。此外,对 SDK 的功能测试还有助于检测 Milvus 系统可能存在的内部问题。除功能测试外,还将对向量数据库进行其他类型的测试,包括单元测试、部署测试、可靠性测试、稳定性测试和性能测试。

云原生和分布式架构为质量保证测试带来了便利和挑战。与本地部署和运行的系统不同,在 Kubernetes 集群上部署和运行的 Milvus 实例可以确保软件测试在与软件开发相同的环境下进行。但缺点是,分布式架构的复杂性带来了更多的不确定性,会使系统的质量保证测试变得更加困难和艰苦。例如,Milvus 2.0 使用了不同组件的微服务,这导致服务和节点数量增加,系统出错的可能性也更大。因此,为了提高测试效率,需要制定更复杂、更全面的质量保证计划。

质量保证测试和问题管理

Milvus 的质量保证包括进行测试和管理软件开发过程中出现的问题。

质量保证测试

Milvus 根据 Milvus 功能和用户需求,按优先顺序进行不同类型的质量保证测试,如下图所示。

QA testing priority 质量保证测试优先级

Milvus 按以下优先顺序对以下方面进行质量保证测试:

  1. 功能:验证功能和特性是否按原设计运行。
  2. 部署:检查用户是否可以使用不同方法(Docker Compose、Helm、APT 或 YUM 等)部署、重新安装和升级 Milvus Standalone 版本和 Milvus 集群。
  3. 性能: 测试 Milvus 中数据插入、索引、向量搜索和查询的性能。
  4. 稳定性:检查 Milvus 能否在正常工作负荷下稳定运行 5-10 天。
  5. 可靠性:测试 Milvus 在发生某些系统错误时是否仍能发挥部分功能。
  6. 配置:验证 Milvus 是否能在特定配置下正常运行。
  7. 兼容性:测试 Milvus 是否与不同类型的硬件或软件兼容。

问题管理

软件开发过程中可能会出现许多问题。模板化问题的作者可以是 QA 工程师本人,也可以是来自开源社区的 Milvus 用户。质量保证团队负责找出问题。

Issue management workflow 问题管理工作流程

问题创建后,首先要经过分流。在分流过程中,将对新问题进行检查,以确保提供足够的问题细节。如果问题得到确认,就会被开发人员接受,并尝试修复问题。开发完成后,问题作者需要验证问题是否已修复。如果是,问题将最终关闭。

何时需要 QA?

一个常见的误解是,质量保证和开发是相互独立的。但事实上,要确保系统的质量,开发人员和质量保证工程师都需要付出努力。因此,质量保证需要参与整个生命周期。

QA lifecycle 质量保证生命周期

如上图所示,一个完整的软件研发生命周期包括三个阶段。

在初始阶段,开发人员发布设计文档,而质量保证工程师提出测试计划、定义发布标准并分配质量保证任务。开发人员和质量保证工程师需要熟悉设计文档和测试计划,这样两个团队才能共同理解发布的目标(功能、性能、稳定性、错误收敛等方面)。

在研发期间,开发和质量保证测试会经常互动,以开发和验证特性和功能,并修复开源社区报告的错误和问题。

在最后阶段,如果符合发布标准,就会发布新版 Milvus 的 Docker 镜像。正式发布时需要发布一份发布说明,重点介绍新功能和已修复的错误,并附上发布标签。然后,质量保证团队也会发布关于此版本的测试报告。

Milvus 中的测试模块

Milvus 中有多个测试模块,本节将详细介绍每个模块。

单元测试

Unit test 单元测试

单元测试有助于在早期阶段识别软件缺陷,并为代码重组提供验证标准。根据 Milvus 拉取请求(PR)验收标准,代码单元测试的覆盖率应达到 80%。

功能测试

Milvus 中的功能测试主要围绕PyMilvus和 SDK 组织。功能测试的主要目的是验证接口是否能按设计运行。功能测试包括两个方面

  • 测试 SDK 在传递正确参数时是否能返回预期结果。
  • 当传递错误参数时,测试 SDK 是否能处理错误并返回合理的错误信息。

下图描述了当前基于主流pytest框架的函数测试框架。该框架为 PyMilvus 添加了一个封装,并通过自动测试界面增强了测试功能。

Function test 函数测试

考虑到需要一种共享的测试方法,以及一些函数需要重复使用,我们采用了上述测试框架,而不是直接使用 PyMilvus 接口。框架中还包含一个 "检查 "模块,为预期值和实际值的验证带来了方便。

tests/python_client/testcases 目录中包含了多达 2700 个功能测试用例,几乎涵盖了 PyMilvus 的所有接口。这些功能测试严格监督每个 PR 的质量。

部署测试

Milvus 有两种模式:单机集群。而部署 Milvus 主要有两种方式:使用 Docker Compose 或 Helm。而在部署 Milvus 后,用户还可以重启或升级 Milvus 服务。部署测试主要分为两类:重启测试和升级测试。

重启测试指的是测试数据持久性的过程,即重启后数据是否仍然可用。升级测试是指测试数据兼容性的过程,以防止在 Milvus 中插入不兼容格式的数据。如下图所示,这两种类型的部署测试共享相同的工作流程。

Deployment test 部署测试

在重启测试中,两个部署使用相同的 docker 映像。但在升级测试中,第一次部署使用的是前一版本的 docker 镜像,而第二次部署使用的是后一版本的 docker 镜像。测试结果和数据保存在Volumes 文件或持久卷索赔(PVC)中。

运行第一个测试时,会创建多个 Collection,并对每个 Collection 进行不同的操作。运行第二个测试时,主要是验证已创建的 Collections 是否仍可用于 CRUD 操作,以及是否可以进一步创建新的 Collections。

可靠性测试

云原生分布式系统的可靠性测试通常采用混沌工程方法,其目的是将错误和系统故障消灭在萌芽状态。换句话说,在混沌工程测试中,我们会有目的地制造系统故障,以便在压力测试中发现问题,并在系统故障真正开始造成危害之前将其修复。在Milvus的混沌测试中,我们选择Chaos Mesh作为制造混沌的工具。有几种类型的故障需要创建:

  • Pod kill:模拟节点瘫痪的场景。
  • 节点故障:测试如果其中一个工作节点 pod 出现故障,整个系统是否仍能继续工作。
  • 内存压力:模拟工作节点大量消耗内存和 CPU 资源的情况。
  • 网络分区:由于 Milvus将存储与计算分离开来,系统在很大程度上依赖于各组件之间的通信。需要对不同 pod 之间的通信进行分区的场景进行模拟,以测试 Milvus 不同组件之间的相互依赖性。

Reliability test 可靠性测试

上图展示了 Milvus 中的可靠性测试框架,可以自动进行混乱测试。可靠性测试的工作流程如下:

  1. 通过读取部署配置初始化 Milvus 集群。
  2. 集群准备就绪后,运行test_e2e.py 测试 Milvus 功能是否可用。
  3. 运行hello_milvus.py 测试数据持久性。创建名为 "hello_milvus "的 Collections,用于数据插入、刷新、索引构建、向量搜索和查询。测试期间不会释放或丢弃此 Collections。
  4. 创建一个监控对象,启动六个线程执行创建、插入、刷新、索引、搜索和查询操作。
checkers = {
    Op.create: CreateChecker(),
    Op.insert: InsertFlushChecker(),
    Op.flush: InsertFlushChecker(flush=True),
    Op.index: IndexChecker(),
    Op.search: SearchChecker(),
    Op.query: QueryChecker()
}
  1. 作出第一个断言--所有操作均按预期成功执行。
  2. 使用 Chaos Mesh 解析定义故障的 yaml 文件,为 Milvus 引入系统故障。例如,故障可以是每五秒杀死一个查询节点。
  3. 在引入系统故障的同时做出第二个断言--判断系统故障期间Milvus操作符返回的结果是否与预期相符。
  4. 通过 Chaos Mesh 消除故障。
  5. 当 Milvus 服务恢复后(意味着所有 pod 都准备就绪),做出第三个断言--所有操作都按预期成功进行。
  6. 运行test_e2e.py 测试 Milvus 功能是否可用。混乱期间的一些操作可能会因为第三个断言而受阻。而即使在混乱消除后,一些操作也可能继续受阻,从而阻碍第三个断言如预期般成功。这一步旨在促进第三个断言,并作为检查 Milvus 服务是否已恢复的标准。
  7. 运行hello_milvus.py ,加载创建的 Collections,并对 Collections 进行 CRUP 操作。然后,检查系统故障前的数据在故障恢复后是否仍然可用。
  8. 收集日志。

稳定性和性能测试

下图描述了稳定性和性能测试的目的、测试场景和指标。

稳定性测试性能测试
目的- 确保 Milvus 能在正常工作负荷下平稳运行一段时间。
- 确保 Milvus 服务启动时资源消耗稳定。
- 测试 Milvus 所有接口的性能。
- 通过性能测试找到最佳配置。
- 作为未来版本的基准。
- 找到妨碍提高性能的瓶颈。
应用场景- 离线读密集型场景,数据插入后几乎不更新,处理每种类型请求的百分比为:搜索请求 90%,插入请求 5%,其他 5%。
- 在线写密集型场景:数据插入和搜索同时进行,每类请求的处理比例为:插入请求 50%,搜索请求 40%,其他 10%。
- 数据插入
- 建立索引
- 向量搜索
指标- 内存使用量
- CPU 消耗
- IO 延迟
- Milvus pod 的状态
- Milvus 服务的响应时间
- 数据插入时的数据吞吐量
- 建立索引所需的时间
- 向量搜索期间的响应时间
- 每秒查询次数(QPS)
- 每秒请求次数
- 调用率
等等。

稳定性测试和性能测试共享同一套工作流程:

Stability and performance test 稳定性和性能测试

  1. 解析和更新配置,并定义指标。server-configmap 对应 Milvus 单机或集群的配置,而client-configmap 对应测试用例的配置。
  2. 配置服务器和客户端。
  3. 数据准备
  4. 请求服务器和客户端之间的交互。
  5. 报告和显示指标。

提高 QA 效率的工具和方法

从模块测试部分,我们可以看到大部分测试的流程其实几乎都是一样的,主要涉及修改 Milvus 服务器和客户端配置、传递 API 参数等。当有多种配置时,不同配置的组合越多样,这些实验和测试所能涵盖的测试场景就越多。因此,代码和程序的重复使用对于提高测试效率至关重要。

SDK 测试框架

SDK test framework SDK 测试框架

为了加快测试过程,我们可以在原有的测试框架中添加一个API_request 封装器,并将其设置为类似于 API 网关的东西。这个 API 网关将负责收集所有的 API 请求,然后将它们传递给 Milvus,让其集体接收响应。之后,这些响应将被传回客户端。这样的设计使得捕获某些日志信息(如参数和返回结果)变得更加容易。此外,SDK 测试框架中的检查器组件可以验证和检查来自 Milvus 的结果。所有检查方法都可以在该检查器组件中定义。

有了 SDK 测试框架,一些关键的初始化过程就可以封装成一个函数。这样就可以省去一大段繁琐的代码。

值得注意的是,每个单独的测试用例都与其独特的 Collections 相关,以确保数据隔离。

在执行测试用例时,pytest-xdist (pytest 扩展)可用于并行执行所有单个测试用例,大大提高了效率。

GitHub 操作

GitHub action GitHub 操作

采用GitHub Action提高 QA 效率还有以下特点:

  • 它是与 GitHub 深度集成的原生 CI/CD 工具。
  • 自带统一配置的机器环境,预装 Docker、Docker Compose 等常用软件开发工具。
  • 它支持多种操作系统和版本,包括 Ubuntu、MacOs、Windows-server 等。
  • 它拥有一个提供丰富扩展和开箱即用功能的市场。
  • 它的矩阵支持并发作业,可重复使用相同的测试流程以提高效率

除了上述特点,采用 GitHub Action 的另一个原因是,部署测试和可靠性测试需要独立、隔离的环境。而 GitHub Action 是对小规模数据集进行日常检查的理想选择。

基准测试工具

为了提高 QA 测试的效率,我们使用了许多工具。

QA tools 质量保证工具

  • Argo:一套用于 Kubernetes 的开源工具,可通过调度任务来运行工作流和管理集群。它还能并行运行多个任务。
  • Kubernetes 仪表盘:基于网络的 Kubernetes 用户界面,用于可视化server-configmapclient-configmap
  • NAS:网络附加存储(NAS)是一种文件级计算机数据存储服务器,用于保存常见的 ANN 基准数据集。
  • InfluxDBMongoDB:用于保存基准测试结果的数据库。
  • Grafana开源分析和监控解决方案,用于监控服务器资源指标和客户端性能指标。
  • Redash:一种帮助可视化数据和创建基准测试图表的服务。

关于深入研究系列

随着 Milvus 2.0正式宣布全面上市,我们精心策划了这个 Milvus 深度剖析系列博客,对 Milvus 架构和源代码进行深入解读。本系列博客涉及的主题包括

Try Managed Milvus for Free

Zilliz Cloud is hassle-free, powered by Milvus and 10x faster.

Get Started

Like the article? Spread the word

扩展阅读