如何定位Milvus性能瓶颈并优化

假设您拥有一台强大的计算机系统或一个应用,用于快速执行各种任务。但是,系统中有一个组件的速度跟不上其他部分,这个性能不佳的组件拉低了系统的整体性能,成为了整个系统的瓶颈。在软件领域中,瓶颈是指整个路径中吞吐量最低的部分。如果机器中的某个齿轮转得不够快,整个系统的速度都会受到影响。因此,及时识别和解决瓶颈问题的重要性不言而喻,能显著提升计算机系统和应用的效率。

在此前的文章中,我们已经介绍了评估各种向量数据库时使用的关键指标和性能测试工具。本文将以 Milvus 向量数据库为例,特别关注 Milvus 2.2 或以上版本,讲解如何监控搜索性能、识别瓶颈并优化向量数据库性能。

性能评估及监控指标

在向量数据库系统中,最常用且最重要的评估指标包括召回率(Recall)、延迟(Latency)和每秒查询数(QPS)。这些指标反映了系统的准确性、响应速度以及能够处理的请求量。

Recall

召回率是指在搜索查询中成功检索到的相关内容的比例。但是,通常并不是所有接近的向量都能被准确识别。这一不足往往源于索引算法的近似性(除了暴搜以外)。这些算法牺牲召回率以换取速度的提升。这些索引算法的配置旨在为特定生产需求寻找一个合适的平衡。更多详细信息,请参阅milvus的文档页面:内存索引和磁盘索引。

计算召回率可能会消耗大量资源,通常由客户端完成。由于确立 Ground truth 需要大量计算,因此通常不会显示在监控仪表板上。在接下来的指南中,我们假定已经达到了一个可接受的召回率水平,且已经为向量索引选定了适当的索引参数。

Latency

延迟指的是响应速度——即从发起查询到接收到结果所需的时间,就好比水从一端流到另一端所需要的时间。较低的延迟可以确保更快的响应速度,这对于实时应用来说非常关键。

QPS

QPS 是衡量系统吞吐量的一个重要指标,它显示了系统每秒能处理的查询数量,类似于水流通过管道的流速。更高的 QPS 值意味着系统能够更有效地处理大量并发请求,这是衡量系统性能的关键因素。

QPS 和延迟之间的关系通常较为复杂。在传统数据库系统中,当 QPS 接近系统的最大容量并耗尽所有资源时,延迟往往会增加。但在 Milvus 中,系统通过批量处理查询来优化性能。这种策略减小了网络数据包的大小,并可能同时提高延迟和 QPS,从而提升系统的整体效率。

性能监控工具

我们将使用 Prometheus 来收集和分析 Milvus 性能。此外,我们还会使用 Grafana 的可视化界面来及时发现性能瓶颈问题。

如何发现性能瓶颈

以下流程图展示了如何使用 Grafana 来有效识别性能瓶颈。图中的黄色菱形框代表需要评估的决策点,浅蓝框则提示具体操作或更多详细信息。在文章接下来的部分中,我们将指导您按照流程图所示的每一步骤监控和诊断性能问题。

前提条件

在开始监控 Milvus 向量数据库的性能之前,请先在 Kubernetes 上部署监控服务,并通过 Grafana 仪表盘对收集的指标进行可视化处理。 更多详细信息,请查阅我们的相关文档页面:

  • 在 Kubernetes 上部署监控服务

  • 设置 Milvus 集群和 K8s

  • 在 Grafana 中可视化 Milvus 指标

重要提示:Grafana 的最小间隔会影响性能监控结果

在开始使用 Grafana 监控 Milvus 前,需要先注意 Grafana 中的最小显示间隔(Minimum interval)可能与设定的间隔不一致。因此,经过平均处理后,图表中的一些尖峰可能会变得更加平滑,或者甚至不再可见。

为了解决这个问题:

  1. 点击指标名称,选择 Edit (编辑)或按下 e 键。

  2. 点击 Query Options(查询选项)。

  3. 将最小间隔(Min interval)改为 15 秒。

重要提示:NUMA 硬件会影响 Milvus 性能

非统一内存访问(NUMA)模式是多处理器系统中采用的一种内存设计方式。在 NUMA 架构下,每个 CPU 核心都直接链接到特定的内存块。访问与执行当前任务的处理器相连的本地内存要比访问连接到其他处理器的远程内存快。当处理器需要从没有直接连接的内存块中获取数据时,因为路径较长,将会产生额外的延迟。

在 NUMA 架构的机器上部署 Milvus 时,推荐使用 numactlcpuset 或类似的工具来分配 Milvus 组件,以保证处理器的亲和性(affinity)。例如,Sapphire Rapids 处理器通常每个 NUMA 节点包含 32 核心,而传统的处理器通常每节点有 16 核心。可以通过在实例上执行 lscpu 命令来确认这一点。

现在,我们可以开始监控 Milvus 的性能,并查找可能存在的性能瓶颈。

1.打开 Grafana 仪表盘

成功在 Kubernetes 上部署监控服务并通过 Grafana 可视化指标之后,请打开 Grafana 仪表盘,如下所示。

注意:本文中,我们采用 Grafana V2 来进行性能监控和瓶颈分析。如果你使用的是 Grafana V1,监控流程可能会有所不同。

2.检查每个组件的 CPU 用量

我们需要检查几个关键组件(Proxy、QueryNode、IndexNode 等)的 CPU 使用情况。要查看每个组件的 CPU 用量,先展开“Overview”(概览)然后选择“CPU usage”(CPU 使用率)。

注意:

  1. 当使用 Milvus 监控 CPU 使用率时,监控数据是在 pod 级别获取的。运行 Standalone Milvus 会显示一条单独的线,代表该 pod 的 CPU 使用情况。运行分布式 Milvus 则可以查看多个 pod 的 CPU 使用情况。在图表中,可以通过一个明显的浅蓝色线条识别 Proxy 的 CPU 使用率,该线条触及上限阈值时,表示已达到 CPU 上限。

  2. 如果面板丢失,且在“Service Quality”(服务质量)下找不到任何图表,您可以:

  • 查看“Runtime”(运行时)下的 CPU Usage。这里显示的是 Kubernetes 的单位使用情况,而非百分比。

  • 或添加 pod 用量面板。点击 “Add”(添加)按钮并选择“Visualization”(可视化)。

  • 输入 PromQL 查询。

    sum(rate(container_cpu_usage_seconds_total{namespace="$namespace",pod=~"$instance-milvus.*",image!="",container!=""}[2m])) by (pod, namespace) / (sum(container_spec_cpu_quota{namespace="$namespace",pod=~"$instance-milvus.*",image!="",container!=""}/100000) by (pod, namespace))
    

  • 选择“Unit”(单位)。

  • 保存设置。

Proxy

当 QPS 较高并且执行网络密集型任务时,如搜索 Top-K 较大、启用 Partition key 以及在输出字段返回向量等,Proxy 可能会成为瓶颈。

如何解决这个问题?

要解决这个问题,您可以:

  • 垂直扩展 Proxy:增加主机的 CPU/内存

  • 水平扩展:增加更多 Proxy pods,并在前端使用负载均衡器(Load balancer)

QueryNode

如果查询节点(QueryNode)的性能受到 CPU 使用率的限制,可能有几个原因,您可以根据以下流程图所示的指示进行操作。

如果某个查询节点的 CPU 使用率达到 100%,如图所示,它可能承担了分发器(Delegator)的角色。

在 Milvus 中,Delegator 的作用类似于军队的指挥官。当搜索请求提交给 Proxy 时,Proxy 首先将请求发送至 Delegator,随后再将其分发到其他 QueryNode 并开始在各个 Segment 上执行搜索。搜索结果将按反向顺序返回。您可以通过选择:QueryNode > DML virtual channel 来验证 QueryNode 是否承担了 Delegator 的角色。

要查看段 Segment 的整体分布情况,请在仪表盘上选择“Query(查询) > Segment Loaded Num(已加载 Segment 数量)”。

如何解决这个问题?

基于您所插入的数据量,维护如此之多的 QueryNode 是否必要?过多的 QueryNode 可能导致 Delegator 需要处理更多的消息,从而降低整体性能。因此,缩减 QueryNode 的数量可能有助于减轻 Delegator 的负担。

另外,还可以考虑垂直扩展 QueryNode——这包括增加托管 QueryNode 的单个 pod 或实例的计算资源,例如 CPU 和内存。这样的调整能够显著提升处理能力,而不增加 Delegator 承担的消息负载。

如果您的数据库是静态的,可以通过手动将数据 Segment 平衡到其他查询节点来解决这个问题,这样 Delegator 就不进行 Segment 搜索,只专注于请求的分发和结果的简化。实施步骤包括:

  1. 在 Milvus 的 YAML 文件中关闭 autoBalance 功能。

  2. 通过 SDK 调用 LoadBalance API。参见:均衡查询负载。

如果您关闭了 autoBalance 并且向数据库中添加了新的向量,您可能需要重新触发 LoadBalance

注意:如果您已经按照上述步骤操作,但 Delegator 仍是性能瓶颈,那么请通过 GitHub 提交问题或直接与我们联系。

IndexNode

当 IndexNote 的 CPU 使用率达到 100% 时,通常是因为 IndexNodes 正在创建索引。如果搜索请求不紧急且新数据的输入暂时中断,建议让 IndexNode 完成索引创建的过程。这样做可以确保在开始任何搜索操作之前,所有的索引都已创建成功。在数据插入的同时进行搜索查询可能会显著降低搜索性能。性能下降的程度受到多种因素的影响,包括您插入向量的方式以及您是否希望在插入后立即返回这些新插入的向量。

如何解决这个问题?

我们提供一些策略可以最小化影响:

  1. 如果条件允许,建议采用批量插入而不是单个插入向量。这可以减少网络传输并绕过“Growing segment”,从而加速数据插入和搜索。更多相关信息,请参考 Bulk insert 文档。

  2. 如果不要求数据即时可见,可以考虑以下建议:

    1. 忽略 Growing segments;在搜索参数中使用 ignore_growing,具体方法请参考 https://milvus.io/docs/search.md。

    2. 在 API 调用是将搜索的一致性等级(Consistency level)设置为 Eventually。更多详情,请参考 https://milvus.io/docs/consistency.md。

其他组件

在 Milvus 的架构中,MixCoord、DataNode 等组件用于高效执行各自的任务,通常不会成为搜索性能的瓶颈。但是,如果监控结果表明这些组件的 CPU 利用率接近或达到满载,暗示可能出现瓶颈,那么请立即扩展这些组件。

3.检查使用的 Milvus 版本

如果您使用的是 Milvus 2.3.x 或以上版本,请跳过此步骤。

Milvus 2.2.x 及以下版本允许用户估算其 CPU 资源消耗,但这一功能在 Milvus 2.3.x 及后续版本中已被删除,因为它可能导致性能问题。

下方图表的 y 轴表示 CPU 数量与百分比的乘积,例如,12个 CPU 的完全利用率在 y 轴上的显示值为1200。

说明:这种估算有时可能会错误地表现为 CPU 的忙碌程度,导致实际 CPU 使用率较低时仍发生任务排队。

如何解决这个问题?

建议将 queryNode.scheduler.cpuRatio 的值调低,其默认值为10.0。

4.检查磁盘性能

如果您在创建索引时选择使用 DiskANN,请检查磁盘性能。

对于 DiskANN 索引类型,推荐使用 NVMe SSD。在 SATA SSD 或 HDD 上创建和搜索磁盘索引可能会因为 I/O 操作受限而导致较大的 Latency 和较低的 QPS。

如需检测磁盘性能,您可以使用 fio 或其他类似的 I/O 性能测试工具来评估 IOPS。一个 NVMe SSD 的 IOPS 应接近 500k。


# Write Testfio -direct=1-iodepth=128 -rw=randwrite -ioengine=libaio -bs=4K -size=10G -numjobs=10 -runtime=600 -group_reporting -filename=/fiotest/test -name=Rand_Write_IOPS_Test# Read Testfio --filename=/fiotest/test --direct=1 --rw=randread --bs=4k --ioengine=libaio --iodepth=64 --runtime=120 --numjobs=128 --time_based --group_reporting --name=iops-test-job --eta-newline=1  --readonly

在 Grafana 中查看 pod 级别的 IOPS:

  1. 在右上角,点击“Pod”,然后选择“Kubernetes / Compute Resources / Pod”。如果您在使用 V2 仪表盘,请点击“Milvus2.0”。

  2. 选择您想要检查的 pod:

  3. 向下滚动并找到“Storage IO”。

如何解决这个问题?
  • 考虑将 SATA SSD 或 HDD 升级到 NVMe SSD,以降低您当前系统的 Latency。多数云服务提供商,例如 AWS,提供 NVMe SSD 的存储选项。比如,AWS 的 m6id 实例在 m6 系列中就配备了基于 NVMe 的本地 SSD。但需要注意的是,虽然 EBS 采用 NVMe 驱动,但其提供的低延迟优势并不及本地 NVMe SSD。

  • 在磁盘索引方面,我们强烈建议选择 NVMe SSD。如果您目前使用的是 SATA SSD 或 HDD,将它们配置为 RAID(独立磁盘冗余阵列)可以帮助减少延迟。

5.检查带宽

带宽限制往往会在系统中形成关键瓶颈,但这种挑战可能往往不会立即显现——可能会出现系统性能提升但 QPS 仍然不变的情况,或者像 gRPC 操作执行时间意外延长这样的间接效果。

理解带宽在这些场景中的角色对于诊断和解决性能限制是至关重要的。例如,在查询维度为 1024 且 TopK 设为 100 的 KNN 搜索请求中,每个请求可能消耗大约 4.8 KB,用于客户端与代理之间的双向通信。1000 的 QPS 意味着大约 4.7 MB的数据通过通道传输。因此,带宽至少应能支持 37 Mbps,以避免拉低 QPS。

虽然初看可能不觉得重要,但提高每秒查询数(QPS)或在输出字段中加入向量会大幅增加所需带宽。举个例子,如果输出字段需要包含向量,上述例子中需要的带宽会上升至至少 3 Gbps。

尽管进行这些计算可能比较繁琐,但使用 Grafana 这类监控工具可以帮助检查进出带宽,有效评估系统性能。

注意:如果您以集群模式部署Milvus,请不要忘记检查Milvus pods之间的带宽。

下图仅显示proxy的网络使用情况:

如何解决这个问题?
  • 增加带宽

      为了应对带宽限制,您可以考虑通过云平台控制台增加带宽,或联系云服务提供商或 DevOps 团队以获得支持。

  • 启用压缩

      我们正在 Milvus 中开发一项新功能,该功能将支持在 Milvus 各组件间以及 Milvus 与 SDK 客户端间实施 gRPC 压缩。通过压缩数据,能够显著降低数据量,虽然这可能因编解码过程而增加 CPU 使用率。预计该功能将在 Milvus 2.4.x 版本中推出,敬请期待!

6.检查性能测试客户端

设想这样一个场景:一个水龙头慢慢地向一根大水管滴水。如果水龙头的出水量很小,那么它将永远无法达到水管的最大容量。同理,当一个客户端每秒只发送少数几个请求时,它无法充分发挥 Milvus 处理大量数据的能力。为了验证客户端是否是性能瓶颈,您可以尝试以下方法:

  • 增加并发数,查看是否有差异。

  • 在不同的计算机或主机上部署多个客户端进行测试。

如何解决这个问题?

如果发现客户端是性能瓶颈,请考虑增加请求的数量。

  1. 检查并调整可能限制数据流的网络限制器。

  2. 如果您使用 PyMilvus:

a.在多进程操作中,选择使用 spawn 方法而非 fork

b.在每一个进程中,执行以下操作:导入 from pymilvus import connections,然后运行 connections.connect(args)

      3.进行水平扩展——增加客户端数量,直至 QPS 值稳定。

联系我们

我们希望这份指南能够帮助您充分提升 Milvus 性能!但如果您无法定位性能瓶颈或在解决性能问题时需要帮助,欢迎随时联系我们。我们随时准备帮助您突破这些挑战!

欢迎通过以下方式联系我们:

  • 提交 GitHub issue

  • 加入 GitHub Discussions

  • 加入 Milvus Discord 社区

点击下方链接,立即体验Zilliz Cloud:

Zilliz Cloud 向量数据库?utm_source=csdn

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/383464.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端网页打开PC端本地的应用程序实现方案

最近开发有一个需求,网页端有个入口需要跳转三维大屏,而这个大屏是一个exe应用程序。产品需要点击这个入口,并打开这个应用程序。这个就类似于百度网盘网页跳转到PC端应用程序中。 这里我们采用添加自定义协议的方式打开该应用程序。一开始可…

吴恩达深度学习笔记1 Neural Networks and Deep Learning

参考视频:(超爽中英!) 2024公认最好的【吴恩达深度学习】教程!附课件代码 Professionalization of Deep Learning_哔哩哔哩_bilibili Neural Networks and Deep Learning 1. 深度学习引言(Introduction to Deep Learning) 2. 神 经 网 络 的 编 程 基 础…

大型语言模型的生物医学知识图优化提示生成

大型语言模型的生物医学知识图优化提示生成 https://arxiv.org/abs/2311.17330 https://github.com/BaranziniLab/KG_RAG 大型语言模型的生物医学知识图优化提示生成 摘要 KG-RAG框架,较好的结合了生物医学知识图谱SPOKE和LLM的优势。SPOKE是一个开放知识图谱&…

【云原生】Kubernetes中的DaemonSet介绍、原理、用法及实战应用案例分析

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,…

59、mysql存储过程

存储过程 一、存储过程: 1.1、存储过程的概念 概念:完成特定功能的sql语句的集合。把定义好的sql集合在一个特定的sql的函数当中 每次执行调用函数即可。还可以实现传参的调用。 1.2、存储过程的语法: delimiter $$ ##delimiter开始和结…

Visual Studio 2022新建 cmake 工程测试 tensorRT 自带样例 sampleOnnxMNIST

1. 新建 cmake 工程 vs2022_cmake_sampleOnnxMNIST_test( 如何新建 cmake 工程,请参考博客:Visual Studio 2022新建 cmake 工程测试 opencv helloworld ) 2. 删除默认生成的 vs2022_cmake_sampleOnnxMNIST_test.h 头文件 3. 修改默认生成的 vs2022_cma…

Docker简单快速入门

1. 安装Docker 基于 Ubuntu 24.04 LTS 安装Docker 。 # 更新包索引并安装依赖包 sudo apt-get update sudo apt-get install -y apt-transport-https ca-certificates curl software-properties-common# 添加Docker的官方GPG密钥并存储在正确的位置 curl -fsSL https://mirror…

叮!2024 龙蜥操作系统大会议题征集正式启动

定啦!2024 龙蜥操作系统大会(OpenAnolis Conference,以下简称“龙蜥大会”)将于 2024 年 8 月 30 日在北京中关村国家自主创新示范区会议中心盛大召开。 2024 龙蜥大会由中关村科学城管委会、海淀区委网信办、中国开源软件推进联…

Python从0到100(四十三):数据库与Django ORM 精讲

前言: 零基础学Python:Python从0到100最新最全教程。 想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Pyth…

Arduino学习笔记1——IDE安装与起步

一、IDE安装 去浏览器直接搜索Arduino官网,点击Software栏进入下载界面,选择Windows操作系统: 新版IDE下载不需要提前勾选所下载的拓展包,下载好后直接点击安装即可。 安装好后打开Arduino IDE,会自动开始下载所需的…

World of Warcraft [CLASSIC] Timebadge

游戏币【每个服务器实时金价不一样,本例子是5000-6000金】 1枚【魔兽世界时光徽章】 30天游戏时间。 5760金币游戏币,策划如何消耗游戏里面的金币总量,以及如何留住那些非人民币玩家呢 30天加上去了 World of Warcraft [CLASSIC] [魔兽世界…

怎么使用动态IP地址上网

如何设置动态IP地址上网? 设置动态IP地址上网的步骤如下: 一、了解动态IP地址 动态IP地址是由网络服务提供商(ISP)动态分配给用户的IP地址,它会根据用户的需求和网络情况实时改变。相比于静态IP地址,动态…

使用VuePress-Reco快速搭建博客(保姆级)

简介:VuePress-Reco 一款简洁的 vuepress 博客 & 文档 主题,可以自由搭建自己的风格,比较方便简洁。 链接:vuepress-reco 准备环境: Node.Js >20.5.0,Npm > 10.8.2 OR Yarn > 1.22.19 注&am…

七、SpringBoot日志

1. 得到日志对象 import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; //打印日志…

【Django】django模板与前端技术(html模板)

文章目录 “python包html”还是“html包python”?1.新建模板2.模板语法3.views.py测试 “python包html”还是“html包python”? 在前端页面中html代码比python多得多,所以一定是html包python最优!于是引出今天的模板。 大体分为三个步骤:…

独立站外链如何影响搜索引擎排名?

独立站的外链对搜索引擎排名有着非常重要的影响。简单来说,外链就像是别的网站对你的网站投的信任票。每一条外链都告诉搜索引擎:“这个网站的内容是有价值的,值得推荐。”因此,外链的数量和质量直接影响你的网站在搜索引擎中的排…

Lc60---1189. “气球” 的最大数量(排序)---Java版

1.题目 2.思路 (1)用字典的方法,ballon,这个单词里面每个字母,需要的个数 (2)再创一个字典的方法统计,输入的字符串的字母的个数 (3)计算能拼凑出多少个“ballon" (4)代码解释 for (char c : text.toCharArray()) {count.put(c, count.getOrDefau…

vue3编程-import.meta.glob实现动态路由(菜单)

import.meta.glob 是vite提供的批量懒加载组件的方法 本地开发环境: const modules import.meta.glob(../views/**/*.vue)这段代码返回的modules是一个Map: key是vue文件的相对路径,值是一个函数,将函数打印出来,如…

Python鲁汶意外莱顿复杂图拓扑分解算法

🎯要点 🎯算法池化和最佳分区搜索:🖊网格搜索 | 🖊发现算法池 | 🖊返回指定图的最佳划分 | 🖊返回指定图的最佳分区 | 🎯适应度和聚类比较功能:🖊图的划分 |…

Python3网络爬虫开发实战(1)爬虫基础

一、URL 基础 URL也就是网络资源地址,其满足如下格式规范 scheme://[username:password]hostname[:port][/path][;parameters][?query][#fragment] scheme:协议,常用的协议有 Http,https,ftp等等;usern…