关于milvus:汽车之家基于-Milvus-的向量检索平台实践

31次阅读

共计 4433 个字符,预计需要花费 12 分钟才能阅读完成。

01

背景

随着计算机技术及机器学习技术的倒退,特征向量作为一种多媒体数据(文本、语音、图片、视频)的形容形式,逐步成熟起来,而向量检索(向量类似计算)也逐步成为一种通用的需要。

向量检索在之家领有十分宽泛的利用场景,如举荐在线业务非明文召回场景,类似视频 / 图片 / 音频去重场景等等。截止到 22 年初,业务方部署了 9 个向量检索引擎去检索向量数据。不过,随着向量检索需要减少,许多问题也接踵而来:

  • 资源节约

每个业务线都会搭建本人的向量检索引擎,资源没有对立治理,会呈现不必要的资源节约。

  • 保护老本

保护向量检索引擎会有一些技术门槛,业务方无奈分心于解决业务,且 Vearch 社区不沉闷,基本上碰到问题都须要业务方本人去解决或者想方法绕过。

  • 开发成本

为了适配新的召回需要,每次上线新的向量接入需要都须要业务方定制化开发。无奈更敏捷地反对在线业务的需要变更。

  • 性能

Vearch的性能也越来越满足不了在线业务的需要,导致在线召回我的项目有较高的超时率,影响线上试验及模型成果。

02

技术选型

之家数据开发团队在 22 年初开始筹备搭建向量检索平台,通过一系列开源计划的调研选型后,咱们最终抉择了 Milvus 作为向量检索平台的底层引擎。Milvus 杰出的架构无论是在稳定性,高可用性,可维护性,功能性及性能等方面都有十分不错的体现

咱们来看下 Milvus 2.x 版本的架构实现特点:

  • 微服务

Milvus 将服务拆成多个角色,每个角色职责划分绝对独立,这样每个角色的源码浏览起来非常容易。简略介绍下 Milvus 的角色职责:

  • ETCD: 负责存储元数据
  • 对象存储: 负责存储向量数据
  • Proxy: Milvus 对立的拜访层
  • DataNode/DataCoord: 负责向量的写入
  • IndexNode/IndexCoord: 负责向量索引的构建
  • QueryNode/QueryCoord: 负责向量的查问
  • RootCoord: 负责解决 DDL 去协调其余 Coord,全局工夫散发,保护以后元数据快照

其中IndexNode/QueryNode/DataNode 这些角色是理论工作的 Woker 节点,IndexCoord/QueryCoord/DataCoord 是负责协调 Woker 节点,是将工作 handoff 给其余角色的节点。

  • 反对云原生

Milvus 服务自身是没有状态的,数据存储在对象存储,元数据会寄存在 ETCD。原生反对 K8s 部署集群部署,咱们能够依据集群或者个别角色的负载去动静扩缩资源。

  • 向量操作读 / 写 / 建索引之间过程级别隔离

如上图,向量读 / 写 / 建索引都是通过不同的节点实现,这样操作之间都是通过过程之间隔离,不会抢占资源,相互影响。

此外,Milvus 还能够在查问的时候指定不同的一致性级别。在实在的业务场景中,一致性要求越强,查问对应的响应工夫也会变长。用户能够依据本人的需要抉择不同的一致性级别。除了 Milvus 杰出的架构能力之外,Milvus 十分沉闷的社区及其背地优良的商业公司 Zilliz 也是咱们抉择 Milvus 的重要起因

03

向量检索平台介绍

目前向量检索平台曾经日益成熟,反对了 30 多个离 / 在线需要。在性能,稳定性,资源节约方面都十分不错的晋升。

基础设施

  • 部署

咱们通过革新 Milvus 原生的部署形式,将 Milvus 集群部署在之家云 K8s 集群中。因为 Milvus 服务自身是无状态的,在 K8s 上,咱们能够依据业务的查问写入需要,灵便地扩缩 Milvus 的服务节点,节约服务器老本。

  • 监控 / 日志

咱们将监控 / 历史日志采集到 Prometheus/ES,能够十分不便地通过监控日志定位问题,配置报警。

  • 索引的抉择

  • IVF-FLAT 倒排索引

    IVF-FLAT 适宜数据量较小的汇合,在咱们的测试场景中,十万级别的数据应用 IVF-FLAT 索引能够失去很好的查问性能。通过调整构建索引参数 nlist 和查问参数 nprobe,在召回准确率和召回性能之间找到适宜业务需要的平衡点。

  • HNSW 图索引

    图索引在大数据量汇合的状况下,相较 IVF-FLAT 能够提供更快的查问性能,然而也会应用更多的内存。目前之家举荐召回次要应用的是 IVF-FLAT 索引,而对于根底数据量比拟大的搜寻数据,HNSW 索引能够提供更高的性能。

  • 正本、分片的抉择

不同的分片数和正本数,对于高并发下的查问性能有显著影响:

  • 对于小数据量汇合(十万数量级)举荐应用一个分片即可,能够通过扩大正本数,进步汇合的并发能力,从而进步查问 QPS。如将正本数设置与 QueryNode 节点数量统一,能够充分利用每一个 QueryNode。
  • 对于千万级别的大汇合比拟容易受到资源限度(内存占用),个别无奈设置太多正本。能够先通过 Milvus 官网提供的计算工具(https://milvus.io/tools/sizing/)评估大略会占用的内存,再依据 quernNode 节点的理论状况确定分片数量。
  • 容量布局

    下图是咱们的压测报告,通过一系列的压测咱们得出结论:

(数据量:109780;索引:lvf-flat;1 分片,10 正本,查问参数:nlist 1024,size 200,noprob 50)

  1. 每个 querynode(12 核 16 GB)可反对 500 QPS
  2. 每个 Proxy(4 核 8 G)可反对 1200 QPS
  3. querynode 与 Proxy 比例倡议为 2:1
  4. 向量平台每个实例能够反对 3500 QPS
  5. 小数据量(< 10 万)场景下,倡议 1 分片多正本。分片数过多会导致性能降落
  6. 以上场景下,cpu 耗费均低于 60%,内存占用低于 10% 且没有持续增长的趋势

04

平台对 Milvus 的一些优化

之前提到咱们抉择 Milvus 的一个重要起因就是 Milvus 十分沉闷的社区和背地优良的商业公司,咱们反馈的问题都会有社区的经营跟进。在咱们对 Milvus 不相熟时,社区的同学会专门来之家为咱们解惑,帮助咱们上线。在享受社区的开源红利的同时,咱们在相熟 Milvus 的过程中还会向社区奉献咱们对 Milvus 的改良:

  • 集成 kafka 的时候指定 kafka 配置

    https://github.com/milvus-io/…

  • 修复 QueryNode metric 相干问题

    https://github.com/milvus-io/…

    https://github.com/milvus-io/…

    https://github.com/milvus-io/…

    https://github.com/milvus-io/…

  • 修复加载配置时未正确开释锁

    https://github.com/milvus-io/…

  • 优化 RootCoord show collection 操作提早

    https://github.com/milvus-io/…

  • 修复小数据量的汇合不能及时加载索引

    https://github.com/milvus-io/…

  • 修复 birdwatcher force-release 删除元数据失败

    https://github.com/milvus-io/…

此外在之家外部还有些通用性低或者形象得不太欠缺的实现,前面欠缺后会和社区探讨是否能够奉献给社区,上面分享两处查问性能方面的优化。

在咱们的测试场景下,在各组件 CPU 使用率失常的状况下,查问索引的性能比较稳定,但通过各组件之间的 RPC 通信后,TP99 就会变得比拟高,根本在 100 ms 以上,在网络环境差的场景影响尤为显著。

以下两处优化实质都是缩小 RPC 申请次数,防止因网络抖动导致 TP99 飙高。

1. 弱一致性查问不去拜访 RootCoord 获取工夫戳

背景:

Milvus 写入的数据和 RoodCoord 发送的心跳都会带有 RooCoord 的工夫戳,会写到 logbroker 外面,QueryNode 会生产数据里的工夫戳更新 servicetime t1。

在做强一致性查问时也会向 RootCoord 查问工夫戳 t2。

QueryNode 只有在 t2>t1 后,能力确保要查问的数据都到齐了之后将查问到的数据返回给 Proxy。

优化:

目前在弱一致性的场景也会向 RootCoord 同步工夫,这个工夫并没有利用在 QueryNode,仅仅是用来做 msgID,在日志里追踪查问行为。因而在弱一致性场景咱们在 Proxy 本地做了工夫戳散发,不会再去申请 RootCoord。这样能够缩小一次 RPC 申请,防止网络起因导致查问 tp99 较高的问题。

2.QueryCoord 调配 Segment 时优先调配给这个正本的 shardleader 节点

背景:

咱们接着介绍下背景:如图咱们看到的是一个汇合某一个正本下两个分片的查问场景。

其中 Proxy 会别离去 QueryNode 申请两个分片的 leader

因为调配 Segment 是基于 QueryNode 持有向量的行数做平衡调配的,每个 shard 的 Segment 可能会被调配到不同的 QueryNode 上

所以 shard leader 须要去其余 QueryNode Search Segment,会额定多一次 RPC 的开销

优化:

针对特地大的数据量汇合的场景,Segment 在 QueryNode 之间负载平衡是十分有必要的。咱们存在一些在线业务场景数据量很小,只会占据很少的资源。然而对查问提早有极高的要求。因而咱们就在 QueryCoord 调配 Segment 时,敞开了 rebalance checker,将 Segment 调配到 ShardLeader 所在的机器。这样就不会有 QueryNode 之间的查问了。

05

利用案例

举荐非明文召回:

非明文召回服务良好地撑持了用户长短期趣味召回模型、双塔召回模型、冷启动召回模型等 23 个算法向量模型数据生产及 24 路非明文召回。

次要流程:

  1. 加工好的向量数据写到 Hive
  2. 配置调度工作将 Hive 数据定期同步到 Milvus 的 AB 表中
  3. 在北斗零碎定制召回及策略交融策略,就能够上线召回模型

最初说一下方才说到的 AB 表性能,向量平台平台目前提供两种数据更新形式,增量更新和用过 AB 表的形式全量更新。

增量更新形式实用于业务数据一直增长,必须以全量数据作为根底数据为业务提供向量检索。比方,图片、文本、视频、音频去重业务。全量更新实用于算法小数据试验,能够疾速看到试验成果,每次试验数据数据会主动隔离,不会相互影响。全量更新能够准确到天、小时、分钟级别,能够满足算法不同需要。

下图是 AB 表的流程,每 5 分钟调度工作会全量同步 Hive 中模型加工好的向量数据,待所有数据写完,索引构建胜利,就会告诉向量平台从查问旧表(图中 collection12091610)切换到新表(collection12091815)。

收益:

  • 性能方面

召回超时率较 Vearch 降落了 3-7 倍

平响较 Vearch 降落了 55%

  • 简化向量接入流程

接入全面配置化,取代了 Vearch 产品须要代码开发的公布形式,上线效率晋升至多 1 倍

06

后续布局

  1. Milvus 的 Upsert 性能未 Release,目前有局部数据量特地大的业务会强依赖这个性能。
  2. 局部去重场景须要强一致性查问,然而目前强统一的查问提早较高,须要和社区一起探讨优化思路。
正文完
 0