Milvus 向量数据库进阶系列丨构建 RAG 多租户/多用户系统 (下)

6064f3135b8bdc2f0968117b50e463b9.png

8281c9f3aa7cbba75c61ef7ceb5c5d14.png

本系列文章介绍

在和社区小伙伴们交流的过程中,我们发现大家最关心的问题从来不是某个具体的功能如何使用,而是面对一个具体的实战场景时,如何选择合适的向量数据库解决方案或最优的功能组合。在 “Milvus 向量数据库进阶” 这个系列文章中,我们会聚焦回答这一类问题,如 “在 AI 应用开发的不同阶段,向量数据库应该如何选型”,“如何正确的构建 RAG 多租系统” 等。虽然这个系列名为进阶,但内容同时适用于初级和进阶用户。我们希望通过这些内容的介绍,帮助大家在向量数据库应用的过程中少走弯路。

01.

背景回顾

上篇文章咱们聊了 to B 大型知识库系统向量数据库中台的多租设计。这篇文章继续这个主题,咱们来聊一聊 to C RAG 场景的向量数据库多用户设计。这类应用的基本特征是涉及个性化对话,如智能助理,情感陪伴,个性化推荐等。典型需求是为每个用户维护独立的对话上下文检索库,通过 RAG 提升对话的连贯性与深度。

这类 to C 的 RAG 多租设计主要需要解决这么几个关键问题:

极高的用户数量。典型的例子如 Character AI, 用户数量或创建的对话机器人实例数量都在千万这个量级。如何在向量数据库中维护千万量级的独立上下文内容是一个比较大的系统设计挑战。

系统持续扩容。考虑到每月巨大的新用户与对话上下文增量,如何完成平稳的系统扩容是第二项挑战。

成本优化。在 to C 的 RAG 应用中,一般活跃用户占比不会超过 10%。特别是对于运营时间较长的项目,由于总注册用户基数大,活跃用户比例在 5% 以内。如何更有效的将系统资源向活跃用户倾斜,并尽可能降低非活跃用户的数据维护成本,是第三项比较大的挑战。

02.

数据隔离粒度与多租支持数量

在深入这几个问题之前,我们先回顾一下向量数据库提供的几个数据隔离层级:

2a776f9a0a69eeb3da40631cfbaec3e1.jpeg

图1. Milvus 数据隔离层级

以 Milvus 为例,数据组织粒度从大到小一共有三种选择:Database,Collection,Partition Key/Partition。上文讲到的 to B 大型知识库系统中,我们一般为每个租户提供一到多个 Database,以满足数据规模及知识库构建灵活度的需要。对于 to C 对话上下文的数据隔离,一般会选择在 Colletion,或 Partition Key 这两层实现。

技术上讲,Collection 提供了更好的隔离性,是数据的表间隔离。而 Partition Key 是逻辑上的表内隔离。我们可以简单的把 Partition Key 理解为一个 Hash 分桶的过程:数据模型上我们将用户的 ID 或独立对话上下文的 ID 作为 Key。数据插入时,向量数据库系统内部会根据每条数据的 Key 进行 Hash,并插入对应的桶。查询时,我们需要在查询语句中将这个 ID 做为过滤条件,系统会找到对应的桶完成查询。

Collection 和 Partition Key 这两个粒度进行数据隔离各有优缺点,等下我们会逐步展开对比。一个快速的选型原则是:如果你的用户数量在几千或万这个量级,你可以考虑为每个用户分配一个 Collection;如果你的用户数量在几百万甚至上千万这个量级,你应该考虑为每个用户分配一个 Partition Key。

假设我们以 32 vCPU,128 GB Memory 的物理资源部署向量数据库。对于 Collection 方案,每个数据库实例大概可以支撑 5000 个用户(即一套系统支撑 5000 个 Collection),以及 1000 个活跃用户 (有读写行为)。平均可支撑的单用户向量数据条数在 5000-10000 (以768维向量估计)。对于这个实例上的所有用户,系统提供 200-1000 左右的总 QPS。考虑公有云常见机型,单用户在向量数据库的硬件成本每年每用户在 ¥3-10 这个区间。

同样的物理资源,对于 Partition Key 方案,单系统可支撑的用户数量在十万级。假设平均每个用户的向量数据条数是 100,单实例可支撑约 30 万用户,其中活跃用户在 1万- 3万。系统提供的总 QPS 在 500 - 2000。单用户在向量数据库的年成本大致是 ¥0.1-0.4。

除了用户总量及单用户成本,每个用户的数据模型是否异构也是选型的重要考量。这里 "数据模型异构" 指的是不同用户的 Collection Schema 是否有差异。在绝大多数 to C 的 RAG 场景中,表的 Schema 都是在应用的业务侧进行设计,用户不会根据自己的应用需求进行自定义,因此是同构的。这样的情况,Collection 或 Partition Key 都可以适用。但如果你的应用中,不同用户的向量数据库表的 Schema 各不相同,就只能选用 Collection 进行数据隔离。因为在同一个 Collection 内,所有的 Partition Key 对应的 Schema 都需要保持一致(如图1中的示例)。

03.

系统持续扩容

像 Milvus 这样相对成熟的向量数据库系统都支持垂直和水平扩展。在项目的早期,我们一般只需要部署一套向量数据库系统实例,通过垂直和水平扩展支撑用户的增长。

119bd2f0389edee9be0606fa4c616c8c.jpeg

图2. 基于 partition key 方案的多租扩容

如果我们采用基于 partition key 的方案,单系统可支撑的用户数量在十万级,甚至超过百万。这时候我们需要在单个系统内通过 Collection 将用户分成若干个组,每个组的所有用户数据放到一个 Collection,用户间数据通过 partition key 机制进行隔离。

同时,我们也需要关注系统异常的爆炸半径。Milvus 提供了 Resource Group 能力,支持 Collection 到物理资源的映射。这样,我们可以将每个用户组所在的 Collection 映射到相互独立的物理查询节点。

随着用户持续增长,当前资源水位较高时,我们可以向系统内并入新的物理节点,并将其绑定至一个新的 Resource Group。这样,我们就扩展了一个新的池子。

d217eb731fe5bd59847d7e42ee837e6c.jpeg

图3. 基于 collection 方案的多租扩容

在项目的高速增长期,不管是出于用户规模的原因,或是进一步提高系统整体稳定性的考虑,我们都可以考虑部署多套向量数据库实例,进而将用户分到多个物理上完全隔离的用户池。在这个架构中,我们需要在应用层和向量数据库层之间增加 Routing 层,避免上下两层间的硬链接,提供统一服务访问地址,以及扩缩容、用户跨数据库调度的灵活性。

如果我们考虑通过 Collection 的方案进行用户间数据隔离,一般单系统实例可支撑的表数量存在上限,超过上限往往会导致系统性能下降或稳定性问题,因此当表的数量接近系统能力上限时,也需要考虑上述架构。

04.

成本优化

在成本优化方面,我们主要考虑利用数据的冷热性质、或用户的活跃性质进行优化。从技术上看,一方面我们希望将热数据/活跃用户数据放置在内存层,保证数据访问的低延迟和高吞吐;另一方面,我们希望将冷数据/非活跃用户数据放置在磁盘层(一般需要SSD),使这部分用户的数据维护成本接近存储成本。

2633fc07543eb064e985097b5c2c933b.jpeg

图4. partition key 的冷热存储

如果我们采用 partition key 方案进行数据隔离,Milvus 提供了 mmap 机制进行冷热数据向多层存储的映射。mmap 本身是操作系统层提供的文件到内存自动映射机制,由操作系统根据数据页的访问热度自动控制页面是否需要加载至内存,或替换到磁盘。

a193a6e24cb2f5034131c8b67940c001.jpeg

图5. collection 的冷热存储

如果我们采用 collection 方案进行数据隔离,同样可以开启 mmap 进行自动的冷热数据管理。与此同时,Milvus 还提供了逻辑层的显式数据加载/释放能力。我们可以通过 load/release 这对操作,在业务层控制是否将一个非活跃用户的 collection 在内存上释放,或将一个回归活跃的用户的 collection 从磁盘加载至内存。

mmap 和 load/release 机制可以结合使用,在这种情况下,一个被 load 到内存的 collection 中如果包含非活跃访问的数据页,也将会被操作系统自动从内存中移除。需要注意的是,在 mmap 机制中,数据从磁盘到内存的移动过程应用侧是不感知的,而 load/release 在应用侧必须感知。向量数据库不能对一个在 release 状态的 collection 进行查询。因此,在考虑使用 load/release 进行 collection 的显式加载/释放时,需要在业务侧设计 collection 的 load/release 触发策略。例如在用户登录时触发 load 进行预加载,或一周无任何访问行为,触发release 释放内存资源。此外,对于较大的 collection,需要考虑 load 操作的数据加载延迟,如果 load 耗时超过秒级,一般在业务侧用户会有感知。

作者介绍

b80007b8ae31d44ca31b78ef7b28c059.jpeg

郭人通,Zilliz 合伙人和产品总监,CCF 分布式计算与系统专委会执行委员。专注于开发面向 AI 的高效并可扩展的数据分析系统。郭人通拥有华中科技大学计算机软件与理论博士学位。

推荐阅读

b8f4435a7235024ac131515530a5b82f.png

22d17aa19f49dcffe643c9ef23d8a500.png76f7aa84b11f50ee2a5f42cafbb71d32.png

81da5ec1180d0c9aa893d8b8aaaa52e3.png

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

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

相关文章

天润融通解开售后维修的成本枷锁,提高维修服务效率

如今,企业客户服务在开展业务咨询和售后受理时,主要方式还是通过电话与在线方式进行。这种方式虽然方便,但是对于一些非常紧急的情况还是显得有些不够。 比如,虽然现在许多企业APP已经实现了一键咨询和一键报修,但当客…

cuda编程[1]:一二三维网格和块的核函数

目录 前言核函数一维二维三维结果分析 前言 所有的代码下载链接:code。以下代码展示了如何在 CUDA 中打印网格和线程的索引信息。代码包括一维、二维和三维的网格和块的设置,并定义了多个内核函数来输出当前的索引信息。 核函数 打印线程索引 __gl…

[MOCO v3] An Empirical Study of Training Self-Supervised Vision Transformers

1、目的 探索基于contrastive/Siamese范式(而非masked auto-encoding范式)和ViT结构(而非卷积网络)的自监督学习 2、方法 MoCo v3 ​​​​​​​ 1)random data augmentation 2)query encoder &a…

shell 学习笔记:数组

目录 1. 定义数组 2. 读取数组元素值 3. 关联数组 4. 在数组前加一个感叹号 ! 可以获取数组的所有键 5. 在数组前加一个井号 # 获取数组的长度 6. 数组初始化的时候,也可以用变量 7. 循环输出数组的方法 7.1 for循环输出 7.2 while循环输出 7.2.1 …

数据结构与算法 第10天(图的应用)

一、最小生成树 生成树:所有顶点均由边连接在一起,但不存在回路 一个图可以有多颗不同的生成树 生成树特点:生成树的顶点个数与图的顶点个数相同; 生成树是图的极小连通子图,去掉一条边则非连通, 一个有 n个顶点的连通图的生成…

idea插件开发之bean复制插件

背景 周末在家无事做,顺手开发了一个之前一直想要做的插件,那就是bean复制插件。 在项目中,由于代码分层设计,对于同样一个数据我们通常会定义不同层的实体,例如xxxEntity、xxxDTO、xxxVO等,这些不同的实…

自然语言处理-词向量转换

文章目录 一、简介1.含义2.基本原理3.常见转换方法1). 独热编码(One-Hot Encoding)2). 词袋模型(Bag of Words, BoW)3). TF-IDF(Term Frequency-Inverse Document Frequency&#xf…

Java IO异常处理:在Web爬虫开发中的实践

在当今的互联网时代,Web爬虫技术已经成为数据采集的重要手段之一。它们能够自动地从网页中提取信息,为数据分析、搜索引擎优化、内容聚合等提供了强大的支持。然而,Web爬虫在执行过程中可能会遇到各种输入/输出(IO)异常…

产品图片小程序开发:全方位指导,让产品展示更出色

想要快速开发并上线一个展示产品图片的小程序吗?乔拓云平台是您的理想选择。只需简单几步,即可打造专属的小程序平台。 首先,访问乔拓云官方网站,注册并登录您的账号。在小程序后端,您可以自由探索丰富的模板库&#x…

Tomato靶机通关攻略

步骤一:进行端口扫描,找寻靶机地址 步骤二:访问靶机地址 步骤三:利用dirb进行扫描 得出:/antibot_image/进行访问 步骤四:进入antibots->info.php->右击进入页面源代码->发现存在文件包含漏洞 步…

猫咪浮毛引起呼吸问题?希喂、小米、有哈宠物空气净化器性能对比

相信每个铲屎官都会碰到猫咪掉毛的问题,掉落堆积的猫毛除了带来的清扫负担,还存在着极大的健康隐患。毛发主要分为两种,大颗粒的猫毛可以被我们肉眼所看见,通常会沉在地面上、床上。这类猫毛我们可以用粘毛器、吸尘器等工具进行清…

window上部署kafka3.6.1,并配置sasl认证

1 安装kafka 第一步安装kafka,并能成功启动,可参考文章Windows下安装Kafka3-CSDN博客 2 修改kafka的配置文件 server.properties是kafka的主要配置文件,里面有很多参数可以调整。 主要修改如下 listenersSASL_PLAINTEXT://127.0.0.1:9092 sasl.enable…

通过Jflash合并程序以 BOOT + APP 合并为例

打开【jflash】新建一个JFash工程 建好后界面如下 打开【File】下面的【Open data file…】 找到Boot程序所在位置 打开后界面如下,可以看到hex中的数据 点击【File】下面的【Merge data file…】 打开应用程序 查看APP地址区域是否有数据&#xff0c…

无人机螺旋桨常见材料!!!

一、常见材料及其特点 复合材料(如玻璃纤维、碳纤维) 特点:轻量化、坚韧、高效。这些复合材料由玻璃纤维、碳纤维等在树脂基体中制成,可以显著提高无人机的飞行效率和稳定性。碳纤维复合材料尤其具有重量轻、抗张强度高、耐腐蚀…

【Docker】构建Harbor仓库

下载软件包地址:https://github.com/goharbor/harbor/releases Harbor 是由vmware公司开源的企业级 Docker Registry 项目。 它提供了以下主要功能和特点: 1. 基于角色的访问控制(RBAC):可以为不同的用户和用户组分…

如何理解 Java 中的阻塞队列:从基础到高级的深度解析

提到阻塞队列,许多人脑海中会浮现出 BlockingQueue、ArrayBlockingQueue、LinkedBlockingQueue 和 SynchronousQueue。尽管这些实现看起来复杂,实际上阻塞队列本身的概念相对简单,真正挑战在于内部的 AQS(Abstract Queuing Synchr…

C:指针学习(1)-学习笔记

目录 前言: 知识回顾: 1、const 1.1 const修饰普通变量 1.2 const修饰指针变量 1.3 总结: 2、指针运算 2.1 指针-整数 2.2 指针-指针 2.3 指针的关系运算 3、指针的使用 结语: 前言: 距离上一次更新关于初…

MLM:多模态大型语言模型的简介、微调方法、发展历史及其代表性模型、案例应用之详细攻略

MLM:多模态大型语言模型的简介、微调方法、发展历史及其代表性模型、案例应用之详细攻略 目录 相关文章 AI之MLM:《MM-LLMs: Recent Advances in MultiModal Large Language Models多模态大语言模型的最新进展》翻译与解读 MLM之CLIP:CLIP…

基于Java+SpringBoot+Vue的新闻稿件管理系统

基于JavaSpringBootVue的新闻稿件管理系统 前言 ✌全网粉丝20W,csdn特邀作者、博客专家、CSDN[新星计划]导师、java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末附源码下载链接🍅 哈…

Mac 安装 jdk 8详细教程

Mac 电脑上安装Jdk 8 的步骤很简单,不用想Windows那样需要配置环境变量PATH、JAVA_HOME。 具体方法如下: 首先,去JDK官网下载对应版本的JDK 8。 这里需要注册一个账号,然后,账号下载。 下载完后,得到一个…