当前位置: 首页 > news >正文

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

本系列文章介绍

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

上期回顾

Milvus作为成熟的开源向量数据库,提供了Milvus Lite、Standalone和Distributed三种部署形态,满足从原型构建到大规模生产部署的不同需求。上篇文章中,我们详细讨论了各形态特点、适用场景及如何根据项目阶段和数据规模选择合适的Milvus部署方式,同时对比了其他开源向量数据库如Qdrant、Weaviate和Chroma的特点和适用规模。本文中,我们将结合Milvus,讲一讲如何构建 RAG 多租户/多用户系统。

图片

现在市面上的 RAG 系统不管是 toB 的还是 toC 的,基本都需要考虑多租。这篇文章我们结合 Milvus,讲一讲如何构建 RAG 多租户/多用户系统。我们会涉及的关键主题有:

  • 用户数据组织与权限控制

  • To B 大型知识库系统的多租户设计

  • To C RAG 应用的多用户设计

  • 非活跃用户的成本控制

本篇是上篇,主要展开前两个主题。

01.

用户数据组织与权限控制

用户数据组织与权限控制相关度比较高,我们结合一些例子放在一起讲。先来看看在向量数据库中怎么合理的组织用户数据。面向生产的向量数据库系统一般都会提供多层数据组织能力。以 Milvus 为例,数据组织粒度从大到小一共有三种选择:Database,Collection,Partition Key/Partition。

图片

图1. Milvus 的多层数据组织结构

图1. 给出了这种结构的大致示例。这里的 Database 指的是一个逻辑上的数据库,概念上和关系型数据库的 Database 接近。Collection 对应的是 Database 内的表。Partition 是表内的数据逻辑分组,具有相同 Partition Key 的数据会被分为同一组。例如我们指定用户 ID 作为 Partition Key,相同用户的数据就会被分到同一个逻辑分组,以方便后续按用户粒度进行数据查询。在权限控制层面,Milvus 提供了比较完善的 RBAC (Role Based Access Control) 机制,系统管理员可以为每一个用户设置数据访问范围以及权限级别。

注意:Milvus 提供了 Partition 和 Partition Key 两种逻辑分组机制,其概念类似,但使用方式略有差异。咱们文中所涉及的都是 Partition Key 这种方式。

从Database、Collection 到 Partition Key,数据组织粒度由大逐渐变小。如果把用户(或租户)映射到更大的粒度(例如为每个用户分配一个 Database),将为用户提供很高的数据组织灵活性,也能适应更广泛的业务需求,但对应的单用户成本也会比较高,整个系统所能支持的用户数量也较少。相反,如果把用户对应到更低的粒度(例如为每个用户分配一个 Partition Key),那么我们可以支持的用户数量会很高,且单用户成本极低,但这种情况下的数据组织需要非常固定,例如所有用户的数据 schema 都需要保持一致。下表总结了不同粒度的主要差异:

图片

 接下来,我们展开聊聊 To B、To C 两种典型 RAG 的多租系统设计。

02.

To B大型知识系统的多租设计

这类场景中,租户数量一般比较少。比如企业内多个独立的业务团队或部门,如果他们都在提供不同的知识库服务,那么对于数据库中台团队,每一个这样的业务团队或部门都是一个租户。

在向量数据库层面,中台团队需要根据业务复杂度为每个租户分配一到多个 Database,业务彼此在 Database 这个粒度进行隔离。这种组织方式几乎把所有的关于 collection 的使用的灵活度都交给了租户:对于 collection 的数据模型、collection 创建数量、不同 collection 上的用户访问权限控制等都不做任何限制。这样的多租设计可以有效支撑不同业务对于向量数据库的差异化使用方式。

图2. 逻辑层到物理层的映射

很多时候,我们需要保障核心业务的服务质量。因此除了 Database 粒度的逻辑隔离,我们还需要关注物理隔离。Milvus 支持逻辑层 Database/Collection 到物理层资源的映射。上图给了一个简单的例子,图中从下到上共出现了三层概念:Query Node,Resource Group,Database。在 Milvus 系统内部,支撑查询任务的组件是 Query Node。每个 Query Node 部署在一个物理节点(如一台物理机或一个Pod)。一到多个 Query Node 可以组成一个 Resource Group,每个 Resource Group 是承载逻辑到物理映射的单元:我们可以将一到多个 Database 或 Collection 映射到一个 Resource Group。

在这个例子中,我们有三个逻辑的 Database,我们假设 Database X 所支撑的知识库很关键,我们不希望 X 受到 Y、Z 的负载干扰。因此我们将 X 单独分配到一个 Resource Group。另外,在图的最右边我们也为 Collection E 单独分配了 Resource Group。注意这里我们讲了两种不同的模式:X 是整个 Database 进行物理隔离,E 是将某个 Database 中的 Collection 单独拿出来进行物理隔离。对于 Database Y、Z 中剩下的所有 Collection,我们让其共享 Resource Group 2 的物理资源。

接下来我们再来看看用户层的设计。通常,企业级知识库的用户都是以只读的方式进行服务访问。很多时候,我们也会关心这些用户产生的问答数据,或希望建立数据与用户的关联。举个例子,考虑一个医院的智能咨询服务台。患者的咨询一般都是一些即时提问,如 "今天专家还有没有临时号"、"采血在几楼" 等。从医院的角度看,希望能够不断的提升问答质量,因此需要对咨询问答对进行记录。注意这些问答对并不会对 RAG 系统的知识库产生直接更新,而是会被写入另外一个专门记录问答的数据库(这里不一定需要向量数据库)。这个库的背后,一般需要一到多名知识库的维护人员,他们通过分析实际的问答数据对知识库做持续迭代。

图片

图3. 企业知识库组成结构

现在,我们把前面讲的所有东西拼成一个整体,其中:

  • 系统管理员负责整个系统的维护,以及系统资源到租户的分配。如分配 Database,确定 Database 到 Resource Group 的映射,Resource Group 的扩容等。

  • 租户(即图中的 Database Owner & Developers)根据业务构建知识库,并根据用户的问答数据持续迭代这个知识库。

  • 用户以只读的方式通过 LLM 间接访问知识库,访问数据持续积累至问答记录库。

在这个例子中,我们的向量数据库系统只针对多租户进行了设计,但并没有针对单个租户的多用户进行设计。即多用户的概念只存在于业务层,向量数据库对此不感知。这里有些同学可能会有疑问:如果我想根据每个用户的历史咨询上下文进行更精准的回答,那不需要在向量数据库中为每个用户维护一个私有的问答上下文吗?这个问题很好,但要看情况。如果是咱们例子中的这类即时咨询,本质是随机性比较高的搜索,影响结果的核心是知识库质量,而非历史上下文。

下期预告

当然,也有不少场景是上下文敏感的。这个时候我们的向量数据库系统就需要感知用户层,并需要为每个用户维护一个上下文记忆。关于这部分多用户的设计,和我们接下来要讲的 To C 场景极为类似,感兴趣的同学可以继续看下篇。

作者介绍

图片

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

相关文章:

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

本系列文章介绍 在和社区小伙伴们交流的过程中,我们发现大家最关心的问题从来不是某个具体的功能如何使用,而是面对一个具体的实战场景时,如何选择合适的向量数据库解决方案或最优的功能组合。在 “Milvus 向量数据库进阶” 这个系列文章中&…...

前缀和(更新中)

目录 1.寻找数组的中心下标 2.除自身以外数组的乘积 3.和为k的子数组 4.可被k整除的子数组 5.连续数组 1.寻找数组的中心下标 . - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int pivotIndex(vector<int>& nums) {int size nums.size();v…...

记录一次单例模式乱用带来的危害。

项目场景&#xff1a; 我们在接受到短信网关下发的回执之后&#xff0c;需要将回执内容也下发给我们的下游服务。为了防止下游响应超时&#xff0c;我们需要将超时的信息存放到Redis中然后进行补发操作。 问题描述 在使用Redis进行数据存储的时候&#xff0c;报NPE问题。 原因…...

外卖项目day14(day11)---数据统计

Apache ECharts 大家可以看我这篇文章&#xff1a; Apache ECharts-CSDN博客 营业额统计 产品原型 接口设计 新建admin/ReportController /*** 数据统计相关接口*/ RestController RequestMapping("/admin/report") Api(tags "数据统计相关接口") Slf…...

养猫科普!牙口不好的猫咪怎么选粮?好吃易消化主食罐推荐

我家的猫猫已经九岁了&#xff0c;已经是一位老奶奶了&#xff0c;她的牙口不太好。对于她来说&#xff0c;膨化猫粮过于硬&#xff0c;很难咀嚼&#xff0c;所以我为她准备了质地柔软的主食罐头。哪种主食罐头更适合牙口不好的猫咪呢&#xff1f;下面&#xff0c;我就来分享一…...

力扣刷题之3143.正方形中的最多点数

题干描述 给你一个二维数组 points 和一个字符串 s &#xff0c;其中 points[i] 表示第 i 个点的坐标&#xff0c;s[i] 表示第 i 个点的 标签 。 如果一个正方形的中心在 (0, 0) &#xff0c;所有边都平行于坐标轴&#xff0c;且正方形内 不 存在标签相同的两个点&#xff0c…...

【更新2022】省级经济高质量发展指标体系测度 含代码 2000-2022

重磅更新&#xff01;【章汕】制作“省级经济高质量发展指标体系测度 含代码”&#xff0c;市面上有这个版本的数据&#xff0c;但其内容非常不全面&#xff0c;个别指标有误&#xff0c;没有stata和代码&#xff0c;即使有代码小白也很容易报错&#xff1b;没有权重、宽面板等…...

缓冲流练习

练习1&#xff1a;拷贝文件 四种方式拷贝文件&#xff0c;并统计各自用时。 字节流的基本流&#xff1a;一次读写一个字节 字节流的基本流&#xff1a;一次读写一个字节数组 字节缓冲流&#xff1a;一次读写一个字节 字节缓冲流&#xff1a;一次读写一个字节数组 这里我只使用了…...

自己履行很多的话语,依旧按照这个方式进行生活

《明朝那些事儿》最后一段讲述了徐霞客的故事&#xff0c;作者当年明月通过徐霞客的生平表达了一种人生哲学。在书的结尾&#xff0c;当年明月写道&#xff1a;"成功只有一个——按照自己的方式&#xff0c;去度过人生"&#xff0c;这句话被用作《明朝那些事儿》的结…...

交通预测数据文件梳理:METR-LA

文章目录 前言一、adj_METR-LA.pkl文件读取子文件1读取子文件2读取子文件3 二、METR-LA.h5文件 前言 最近做的实验比较多&#xff0c;对于交通预测数据的各种文件和文件中的数据格式理解愈加混乱&#xff0c;因此打算重新做一遍梳理来加深实验数据集的理解&#xff0c;本文章作…...

按钮类控件

目录 1.Push Button 代码示例: 带有图标的按钮 代码示例: 带有快捷键的按钮 代码示例: 按钮的重复触发 2.Radio Buttion 代码示例: 选择性别 代码示例: click, press, release, toggled 的区别 代码示例: 单选框分组 3.3 Check Box 代码示例: 获取复选按钮的取值 1.Pu…...

opencascade AIS_ViewController源码学习 视图控制、包含鼠标事件等

opencascade AIS_ViewController 前言 用于在GUI和渲染线程之间处理视图器事件的辅助结构。 该类实现了以下功能&#xff1a; 缓存存储用户输入状态&#xff08;鼠标、触摸和键盘&#xff09;。 将鼠标/多点触控输入映射到视图相机操作&#xff08;平移、旋转、缩放&#xff0…...

拉削基础知识——拉床的类型及特点

拉床是所有机械加工工具中最简单的一种&#xff0c;由拉削工具、夹具、驱动装置和支撑架组成。拉削加工可获得较高的尺寸精度和较小的表面粗糙度&#xff0c;生产率较高&#xff0c;适用于大批量生产。拉床按其结构主要分为卧式和立式。应用领域和功能可分为液压拉床、自动拉床…...

docker-compose笔记

docker 目前docker官网已经无法登录&#xff0c;但是还可以从清华镜像站&#xff08;https://mirrors.tuna.tsinghua.edu.cn/docker-ce/&#xff09;下载。 使用方法可以参考早期文章《docker笔记》 docker-compose 可以从Github下载不同版本的二进制文件&#xff0c;例如do…...

C# 自定义控件无法加载

问题 在做winform开发时自己定义了一个控件&#xff0c;控件在工具箱中显示了&#xff0c;但是拖动到窗体设计器时会提示未能加载工具箱项xxx&#xff0c;将从工具箱中将其删除&#xff0c;如下图所示: 点击确定后&#xff0c;控件会从工具箱中移除。 解决方法 将 生成>…...

avl树自实现(带图),探讨平衡因子与旋转

引子&#xff1a; 在此之前&#xff0c;我们学过了搜索二叉树&#xff0c;这种树&#xff0c;在如果数据有序或接近有序的情况下&#xff0c;二叉搜索树将退化为单支树&#xff0c;查找元素相当于在顺序表中搜索元素&#xff0c;效率低下&#xff0c;而且普通搜索二叉树无法有…...

Elasticsearch 的DSL查询,聚合查询与多维度数据统计

文章目录 搜索聚合高阶概念 搜索 即从一个索引下按照特定的字段或关键词搜索出符合用户预期的一个或者一堆cocument&#xff0c;然后根据文档的相关度得分&#xff0c;在返回的结果集里并根据得分对这些文档进行一定的排序。 聚合 根据业务需求&#xff0c;对文档中的某个或…...

【如何高效处理前端常见问题:策略与实践】

在快速发展的Web开发领域&#xff0c;前端作为用户与应用程序直接交互的界面&#xff0c;其重要性不言而喻。然而&#xff0c;随着技术的不断演进和项目的复杂化&#xff0c;前端开发者在日常工作中难免会遇到各种挑战和问题。本文旨在深入探讨前端开发中常见的问题类型&#x…...

聊聊前端 JavaScript 的扩展运算符 “...“ 的使用场景

前言 在 JavaScript 中&#xff0c;... 被称为 “扩展运算符” 或 “剩余参数运算符”。 扩展运算符是在 ES6&#xff08;ECMAScript 2015&#xff09;中被引入的&#xff0c;目的是为了提高语言的表达能力和代码的可读性。 根据上下文不同&#xff0c;它主要用在数组、对象…...

华为续签了,但我准备离职了

离职华为 今天在牛客网看到一篇帖子&#xff0c;名为《华为续签了&#xff0c;但我准备离职了》。 讲得挺真诚&#xff0c;可能也是一类毕业进华为的同学的心声。 贴主提到&#xff0c;当年自己还是应届毕业的时候&#xff0c;手握多个 offer&#xff0c;最终选的华为&#xff…...

【Python】 -- 趣味代码 - 小恐龙游戏

文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

微信小程序云开发平台MySQL的连接方式

注&#xff1a;微信小程序云开发平台指的是腾讯云开发 先给结论&#xff1a;微信小程序云开发平台的MySQL&#xff0c;无法通过获取数据库连接信息的方式进行连接&#xff0c;连接只能通过云开发的SDK连接&#xff0c;具体要参考官方文档&#xff1a; 为什么&#xff1f; 因为…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

抽象类和接口(全)

一、抽象类 1.概念&#xff1a;如果⼀个类中没有包含⾜够的信息来描绘⼀个具体的对象&#xff0c;这样的类就是抽象类。 像是没有实际⼯作的⽅法,我们可以把它设计成⼀个抽象⽅法&#xff0c;包含抽象⽅法的类我们称为抽象类。 2.语法 在Java中&#xff0c;⼀个类如果被 abs…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

如何在Windows本机安装Python并确保与Python.NET兼容

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...