您现在的位置是:首页 > 文章详情

得物向量数据库落地实践

日期:2025-08-01点击:24

一、背景

信息通信技术(ICT)正经历着前所未有的变革浪潮,以大模型和生成式人工智能(GenAI)为代表的技术突破,正在引发全球产业体系的深刻变革,成为驱动企业技术架构革新和商业模式转型的关键引擎。

得物是广受年轻人喜爱的品质生活购物社区。在AI鉴别、图搜、算法、安全风控等场景下都广泛使用了GenAI技术。

向量数据库作为GenAI的基础设施之一,通过量化的高维空间数据结构(如HNSW算法),实现对嵌入向量(Embeddings Vector)的高效存储、索引和最近邻搜索(ANN),支撑包括多模态数据表征在内的复杂智能应用。

二、认识向量数据库

向量数据来源和存储

一般向量数据库中向量的来源是将图片、音频、视频、文本等非结构化数据,将这些非结构化数据通过对应的量化算法计算出一个多维度的向量(生产使用一般向量维度会大于512),并且将向量数据持久化在特定的存储上。

向量数据库是如何工作

向量数据库在查询的时候一般会将需要查询的非结构化数据通过量化,计算成一个多维度向量数据,然后在数据库中搜索出和查询向量相似的数据。(需要注意的是这边查询的是相似的数据而不是相同的数据)。

三、向量数据库对比传统数据库

向量数据库在数据结构、检索方法、擅长领域与传统数据库有很大的不同。

传统数据库

结构是处理离散的标量数据类型(例如数字和字符串),并通过行和列来表达组织数据(就是一个表格)。传统数据库主要为了解决结构化数据的精确管理和高效查询问题。并且传统数据库通过B树索引、哈希索引等数据结构,能够快速定位到精确匹配的记录。更重要的是,传统数据库通过ACID事务特性(原子性、一致性、隔离性、持久性)确保了在数据中数据的绝对准确性。

向量数据库

为了解决非结构化数据的语义搜索问题,解决如何在海量的高维向量数据中,快速找到与查询向量最相似的结果。比如在推荐系统中找到与用户喜好相似的物品,或在图像库中检索出与查询图片最相近的图片。这类问题的特点是:

  1. 查询的不是精确匹配,而是相似度排名。
  2. 数据维度极高(通常128-2048维)。
  3. 数据规模庞大(可能达到十亿级别)。

传统数据库的精确查询方式在这种场景下完全失效,因为:

  1. 无法为高维向量建立有效的B树索引。
  2. 计算全量数据的精确相似度代价过高。
  3. 无法支持"相似但不完全相同"的搜索需求。

四、如何选择向量数据库

向量数据库比较

下面我们通过10个不同维度来比较一下不同向量数据库的区别:

从上面表格可以看到:

  1. 自 2016 年起 ,向量数据库逐渐崭露头角,成为 AI 和大数据领域的重要基础设施。而到了 2021 年之后 ,随着深度学习、大模型和推荐系统的迅猛发展,向量数据库正式迈入爆发式增长时代 ,成为现代数据架构中不可或缺的核心组件。
  2. 超过半数的向量数据库均采用分布式架构设计,并且这些支持分布式部署的系统普遍具备弹性扩缩容能力,能够根据业务需求实现资源的动态调整。
  3. 当业务需要处理亿级甚至更高规模的向量数据时,推荐以下高性能、可扩展的向量数据库:Vespa、Milvus/Zilliz、Vald、Qdrant。
  4. 当前主流的向量数据库普遍采用模块化、插件式的设计理念。其核心引擎大多基于 C/C++ 开发,以追求极致的性能表现。与此同时,Go 和 Rust 也正在这一领域崭露头角。
  5. 在向量数据库领域,HNSW(Hierarchical Navigable Small-World)和 DiskANN 正逐渐成为主流索引方案。其中HNSW主要以内存搜索为主,DiskANN主要以磁盘搜索为主。值得注意的是,Qdrant 在优化 HNSW 的基础上,进一步实现了 基于磁盘的 HNSW 检索能力。

选择流行的索引

在向量数据库技术领域,有HNSW 和 DiskANN 作为两大主流索引方案,各自展现了独特的技术优势。我们从以下关键维度进行专业对比分析。 从上表格我们可以得到,HNSW和DiskANN适用于不同的场景:

  1. HNSW :以 内存优先 的设计实现高性能搜索,适合 低延迟、高吞吐 要求严格的场景,如实时推荐、广告检索等。
  2. DiskANN :以 磁盘存储优化 为核心,在保证较高召回率的同时 显著降低硬件成本 ,适用于大规模数据下的经济型检索需求。

随着数据规模的持续增长,HNSW 和 DiskANN 的混合部署模式 或将成为行业标准,让用户能根据业务需求灵活选择 "极致性能" 或 "最优成本" 的检索策略。

综合比较和选择

从表格中可以得到:

  1. 如果数据流比较小,并且自身对Redis、PG、ES比较熟悉,就可以选择Redis、PG、ES。如DBA团队就比较适合。
  2. 如果数据量比较大,并且前期人力不足可以使用云托管方案。选择Zilliz、Pinecone、Vespa或者Qdrant,如果后期计划从云上迁移到自建可以选择Zilliz、Vespa或者Qdrant。

得物选择Milvus作为向量数据库

我们的需求

社区图搜和AI鉴别需要大量的数据支持,得物业务场景要求能支持十亿级向量数据搜索,有如下要求:

  1. 大数据量高性能搜索,RT需要在90ms以内。
  2. 大数据量但是性能要求不高时,RT满足500ms以内。

需要支持快速扩缩容:

满足上面2点就已经锁定在Milvus、Qdrant这两个向量数据库。如果从架构复杂度和维护/学习成本的角度考虑,我们应该优先选择Qdrant,因为它的架构相比Milvus没有那么复杂,并且维护/学习成本没有Milvus高,重要的Qdrant可以单独集群部署,不需要k8s技术栈的支撑。

Milvus 和 Qdrant 架构比较

Milvus架构:Milvus部署依赖许多外部组件,如存储元信息的ETCD、存储使用的MinIO、消息存储Pulasr 等。

Qdrant:Qdrant完全独立开发,支持集群部署,不需要借助ETCD、Pulsar等组件。

选择Milvus的原因

※ 业务发展需求

业务属于快速发展阶段,数量的变化导致扩缩容频繁,使用支持k8s的Milvus在扩缩容方面会比Qdrant快的多。

※ 技术储备和社区良好

对DBA而言,向量数据库领域需要持续的知识更新和技术支持。从问题解决效率来看,国内技术社区对Milvus的支持体系相较于Qdrant更为完善。

※ 契合得物DBA开发栈

Milvus使用的开发语言是Go,契合DBA团队技术栈,在部分运维场景下,通过二次开发满足运维需求。例如:使用milvus-backup工具做迁移,部分的segment有问题需要跳过。自行修改一下代码编译运行即可满足需求。

五、Milvus在得物的实践

部署架构演进

小试牛刀

初始阶段,我们把Milvus部署在K8S上,默认使用HNSW索引。架构图如下,Milvus整个架构较为复杂,外部依赖的组件多,每个集群需要部署自己的 ETCD、ZK、消息队列模块,多套集群共享着同一个存储。

存储拆分,每个集群独立存储

共享存储瓶颈导致稳定性问题凸显。

随着业务规模扩展,集群数量呈指数级增长,我们观测到部分集群节点出现异常重启现象,经诊断确认该问题源于底层共享存储存在性能瓶颈。

独立资源池迁移至共享资源池

通过混布的方式提升资源利用率。

前期为了在性能和稳定性上更好的服务业务,Milvus部署的底层机器都是独立的,目的就是为了和其他应用隔离开,不相互影响。但是随着集群的越来越多,并不是所有的集群对稳定性和性能要求那么高,从监控上看Milvus集群池的资源使用不超过10%。为了提高公司资源利用率,我们将独立部署的Milvus迁移高共享资源池中,和大数据、业务应用等K8S部署相关服务进行混合部署。

DiskANN索引的使用

数据量大且搜索QPS小时选择DiskANN 作为索引。通过监控发现有很多集群数据量比较大,但是QPS并不是那么高,这时候就考虑对这些性能要求不高的集群是否有降本的方案。通过了解我们默认使用的HNSW索引需要将所有数据都加载到内存中进行搜索,第一反应就是它的内存查询和Redis一样,那是否有类似pika的方案内存只存少部分数据大部分数据存在磁盘上。这时候发现DiskANN就能达到这样的效果。

性能压测

※ 集群规格 QPS 延时(ms)

新增DiskANN索引后集群架构

增加DiskANN后我们需要对相关服务器上挂载 NVME SSD 磁盘,用于在磁盘上搜索最终数据。

DiskANN 加载数据过程

引入Zilliz

经过大规模生产验证,Milvus在实际业务场景中展现出卓越的性能表现和稳定性,获得业务方的高度认可。并且也吸引来了C端核心业务系统的使用。在使用前,我们使用了业务真实流量充分的对Milvus进行了压测,发现Milvus在亿级别数据量的情况下满足不了业务,因此对于部分核心场景我们使用了Zilliz。

Milvus和Zilliz 压测

业务的要求是集群返回的RT不能操过90ms。

使用真实的业务数据(亿级别)和业务请求对Milvus进行压测,发现Milvus并不能满足业务的需求。

Milvus RT 200不满足业务需求,并且QPS一直上不去,无论我们对QueryNode扩容多大,其中还发生过,将Query扩容到60个后,反而RT上升的问题,排查后是因为有的QueryNode和Proxy交互的时候网络会抖动影响了整体的RT。

从上面可以看出就算业务能容忍RT=200ms的,Milvus也需要创建3个相同的集群提供业务访问,并且业务需要改造代码实现多写、多读的功能,最终还会发现3个集群的成本远高于Zilliz。

通过成本和性能上的考虑,对于大数据量并且性能和稳定性要求高场景,我们将选用Zilliz。

迁移方案

对于不同业务场景,我们分别制定了以下3种迁移方案:

方案1:业务自行导入数据使用

方案2:备份恢复 + 业务增量

方案3:全量 + 增量 + 业务双写/回滚

高可用架构部署

随着业务关键性持续提升,Milvus对应的SLA变得越来越重要。在此背景下,构建完善的Milvus高可用架构与灾备体系已成为系统设计的核心考量要素。比如:主从、多zone部署,Proxy高可用,Minio高可用,一个zone完全挂了怎么办等问题?

方案1: 同城多机房混部 正常访问:

当 Zone1 不可用:

  1. 访问会切换到 Zone 2 的备用SLB中。
  2. 备用SLB会访问本机房的Proxy。
  3. 由于 QueryNode 1 和 QueryNode 2 已经不可用,需要重建QueryNode,新生成 QueryNode 5、QueryNode 6并且加载数据提供访问。

方案2: 同城多zone多副本就近访问

整个Zone不可用: 当Zone1整个不可用,不影响Zone2的访问。

方案3: 同城多zone单独部署业务交叉访问互相backup

当整个zone不可用 整个zone1不可用,由于线路1会访问到zone1的SLB,因此线路1访问会报错,业务需要将线路1切换成线路2。

六、向量数据库运维沉淀

索引结构和搜索原理

HNSW 索引

※ 相关信息

※ 内存结构

由于空间问题,图中并没有完全按 M=16、ef=200 参数进行画图。

※ HNSW搜索过程 现在需要搜索向量N = [....]

DiskANN 索引 ※ 相关信息

※ 存储结构和裁剪过程

由于画图空间问题,没办法将 聚类数=10、100/内存聚类、1w/磁盘聚类 信息画全。

  1. 初始化随机连接:DiskANN算法会将向量数据生成一个密集的网络图,其中点和点是随机链接的,并且每个点大概有500个链接。
  2. 裁剪冗余链接:通过计算点和点点距离裁剪掉一些冗余的链接,留下质量高的链接。
  3. 添加快速导航链接:计算出图中若干个中心点,并且将这些中心点进行链接,并且这些链接会跳过其他点,如果图中黄色链接。
  4. 重复进行裁剪优化过程,达到最优的情况。
  5. PQ量化操作生成索引:
    1. 将向量分成多个子空间。
    2. 独立对每个子空间进行聚类操作,并且计算出多个质心。
    3. 将每个子向量映射到最近的质心ID。

※ DiskANN搜索过程

现在需要搜索向量N = [....]

并不是你想的那样

querynode 越多越快? querynode 越多,查询越快,并发越高?

※误区原因 将querynode看成redis cluster,增加节点数能提高查询并发,然而并不是。redis cluster 增加节点,数据量会尽可能的打散到每个节点中,所以增加节点和性能提升是相对成正比。但是milvus不一样,milvus打散的基本单位是segment,一般segment大小(1G/个),他的粒度比redis cluster要大。理论上的理想情况是1个segment对应1个querynode,但是实际情况会收到多因素的干扰,会导致querynode越多出现不稳定的概率越大,如某个querynode网络抖动会影响整体的查询RT。

标量索引提高性能

在标量上创建索引,搜索带上标量过来能提高性能?

※误区原因

使用传统关系型数据库的索引查询来理解Milvus的索引查询,字段上创建了索引能使用到索引扫描进行数据查询,比全表扫描快。然而并不是,关系型数据库的属于精确查询,Milvus属于近似最近邻搜索(ANNS),milvus的查询是不保证绝对精确,使用了标量索引查询反而会导致数据变稀疏查询会变慢。

使用标量索引筛选不一定快原因,如下示例:

通过ANNS搜索后再使用标量搜索,过程如下:

思考:

在第二步如果使用ANNS搜索完成之后到底是否需要使用标量索引进行搜索。 如果需要使用标量索引进行搜索那边在ANNS搜索后的结果集需要额外的进行索引构建,然后再进行过滤。构建构建过程其实也是需要便利结果集,那么是不是可以直接在便利的时候直接进行结果集的筛选。 那么其实在某种程度上是不是标量索引没那么好用。

大量单行dml不批量写入能提高数据库性能 大量单行dml,不使用批量写入操作,能提高数据库性能。

※误区原因 使用传统关系型数据库为了让系统尽量少的大事务,减少锁问题并且提高数据库性能。然而实际上Milvus如果有很多的小事务反而会影响到数据库的性能。因为Milvus进行dml操作会生成deltalog、insertlog,当dml都是小事务就会生成大量的相对较小的deltalog和insertlog文件,deltalog和insertlog在和segment做合并的时候会增加打开和关闭文件次数,并且增加做合并次数,导致io一直处于繁忙状态。

deltalog 和 insertlog 生成的契机有2种:

  1. 当数据量达到了一定的阈值会进行生成deltalog 或 insertlog。
  2. Milvus会定时进行生成deltalog 或 insertlog。

eltalog、insertlog 和 segment 合并过程

人为让 deltalog、segment 执行时机可预测

如果业务对数据实现要求不是那么高,建议使用定时批量的方式对数据进行写入,比如可以通过监控获取到每天的波谷时间段,在波谷时间段内进行集中式数据写入。原因是如果不停的在做写入,无法判断进行合并segment的时间点,要是在高峰期进行了合并操作,很有可能会影响到集群性能。

错误处理

※ 2.2.6 批量删除数据bug,导致业务无法查询 报错:

解决:将集群升级到2.2.16,并且让业务 批量删除和写入数据。 ※ find no available rootcoord, check rootcoord state

报错:

问题:rootcoord和其他pod通信出现了问题。

解决:先重建rootcoord,再依次重建相关的querynode、indexnode、queryrecord、indexrecord。

※ 页面查询报错 (Search 372 failed, reason Timestamp lag too large lag)

问题:pulsar 组件对应相关pod问题导致不进行消费。

解决:将pulsar 组件相关pod进行重建,查看日志,并且等待消费pulsar完成。

※ Query Node 限制内存不足 (memory quota exhausted)

报错: <MilvusException: (code=53, message=deny to write, reason: memory quota exhausted, please allocate more resources, req: /milvus.proto.milvus.MilvusService/Insert)> 原因:配置中Query Node配置内存上线达到瓶颈。

解决:增加Query Node配置或者增加QueryNode节点数。

※ 底层磁盘瓶颈导致ETCD访问超时

报错:

解决:从架构方面上进行解决,在集群维度将磁盘进行隔离,每个集群使用独立磁盘。

七、未来展望

数据迁移闭环

数据迁移闭环:对于业务数据加载到向量数据库的场景,业务只关心数据的读取和使用,不需要关心数据的量化和写入。DBA侧建立数据迁移闭环(下图绿色部分)。

数据准确性校验

对于上游数据(如MySQL)和下游向量数据库数据库一致性校验问题,DBA业将协同业务、Milvus进行共建校验工具,保障数据的准确性。

往期回顾

1.社区搜索离线回溯系统设计:架构、挑战与性能优化|得物技术

2.从Rust模块化探索到DLB 2.0实践|得物技术

3.eBPF 助力 NAS 分钟级别 Pod 实例溯源|得物技术

4.正品库拍照PWA应用的实现与性能优化|得物技术

5.汇金资损防控体系建设及实践 | 得物技术

文 / 呆呆 少晖

关注得物技术,每周更新技术干货 要是觉得文章对你有帮助的话,欢迎评论转发点赞~ 未经得物技术许可严禁转载,否则依法追究法律责任。

注:本文部分代码上传代码可读性差,换成截图上传,需要复制代码的小伙伴可以去得物技术公众号查询。

原文链接:https://my.oschina.net/u/5783135/blog/18686778
关注公众号

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。

持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。

文章评论

共有0条评论来说两句吧...

文章二维码

扫描即可查看该文章

点击排行

推荐阅读

最新文章