📘 第一部分:基础与原理篇
Q1:请简述向量数据库与传统关系型数据库(如MySQL)的核心区别是什么?为什么大模型应用(如RAG)必须使用向量数据库?
A:
- 核心区别 :
- 数据模型 :MySQL 处理结构化数据(行/列),擅长精确匹配(如
WHERE id=1);Milvus 处理非结构化数据的嵌入向量 (高维数组),擅长语义相似度搜索。 - 索引结构 :MySQL 使用 B+ 树、Hash 索引;Milvus 使用 HNSW、IVF 等专为高维向量设计的索引。
- 一致性 :MySQL 追求 ACID 强一致性;Milvus 追求高召回率 和低延迟(最终一致性)。
- 数据模型 :MySQL 处理结构化数据(行/列),擅长精确匹配(如
- RAG 的必要性 :大模型存在知识滞后和幻觉。向量数据库能将海量外部知识转化为向量存储,通过近似最近邻搜索快速找到与用户问题语义最相关的上下文,作为"外挂大脑"喂给 LLM,从而解决幻觉并扩展知识库。
Q2:Milvus中的"集合"与关系型数据库中的"表"有何异同?在Milvus 2.x版本中,Schema设计包含哪些关键字段?
A:
- 异同 :Milvus 的 Collection(集合)类似 MySQL 的 Table(表),但 Collection 是Schema-on-write(写入时定义结构),必须预先定义 Schema。
- 关键字段 :
- 主键 :
INT64或VARCHAR,用于唯一标识实体。 - 向量字段 :存储 Embedding 向量(如
FLOAT_VECTOR),需指定维度(dim)。 - 标量字段 :用于过滤的元数据(如
title,date,category),支持布尔、整型、字符串等。
- 主键 :
Q3:什么是近似最近邻搜索?为什么在大规模数据场景下,我们通常选择ANN而不是KNN(精确最近邻)?
A:
- 定义:ANN 旨在寻找"足够相似"的邻居,而不是"最相似"的那个。
- 原因 :KNN(精确搜索)需要计算查询向量与库中每一个向量的距离,复杂度为 O(N)O(N) 。当数据量达到亿级时,耗时不可接受。ANN 通过预建索引(如聚类、图结构),牺牲极少量的精度(召回率),将搜索复杂度降低到 O(logN)O(logN) 甚至更低,实现毫秒级响应。
Q4:请对比HNSW和IVF_FLAT两种索引算法的原理及适用场景。如果业务对内存敏感且数据量达到亿级,你会选择哪种索引?
A:
- HNSW :基于图结构,分层导航。特点 :查询速度极快,召回率高,但内存占用极大,构建索引慢。
- IVF_FLAT :基于聚类(倒排索引)。特点 :内存占用较小,适合亿级以上大规模数据。
- 选择 :亿级数据且内存敏感,首选 IVF_FLAT 或 IVF_SQ8(量化压缩)。
Q5:在Milvus中,nprobe和nlist参数分别代表什么含义?调整它们会对检索的召回率和QPS产生怎样的影响?
A:
- nlist:聚类中心数量(IVF 索引参数)。通常建议设为 NN (N为向量总数)。
- nprobe :搜索时探测的聚类数量。
- 调大
nprobe:搜索更细致,召回率提高 ,但QPS 下降(耗时增加)。 - 调小
nprobe:搜索更快,QPS 提高 ,但召回率下降。
- 调大
Q6:Milvus支持哪些相似度度量方式?在使用余弦相似度时,对向量数据有什么特殊的预处理要求?
A:
- 度量方式 :
- L2:欧氏距离,值越小越相似。
- IP:内积,值越大越相似。
- COSINE:余弦相似度。
- 预处理要求 :使用 COSINE 时,必须在插入前对向量进行归一化处理(使其模长为 1),否则检索结果可能不准确。
🏗️ 第二部分:架构与运维篇
Q7:Milvus 2.x采用了存算分离的架构,请简述Proxy、QueryNode、DataNode和IndexNode这四个核心组件的职责是什么?
A:
- Proxy:接入层,负责鉴权、请求路由、时间戳分配。
- QueryNode :计算层,负责加载索引,执行向量检索和标量过滤。
- DataNode :写入层,负责将数据写入消息队列(MsgPack)和持久化到对象存储。
- IndexNode :索引层,负责异步构建向量索引。
Q8:在Milvus中,数据写入流程是怎样的?请描述从SDK发起插入请求到数据最终持久化在对象存储的全过程。
A:
- SDK 发送插入请求给 Proxy。
- Proxy 将数据写入 MsgPack(如 Pulsar/Kafka)。
- DataNode 订阅消息,将数据写入对象存储(MinIO/S3)进行持久化(生成 Insert Log),同时生成 Binlog。
- IndexNode 异步读取数据构建索引。
- QueryNode 加载索引后,数据才变得可被搜索。
Q9:Milvus是如何实现水平扩展的?当QueryNode负载过高时,系统是如何自动平衡查询负载的?
A:
- 扩展机制:Milvus 基于 K8s 部署,组件无状态(除 Coord 组件外)。增加 QueryNode 实例即可扩展查询能力。
- 负载均衡 :RootCoord/DataCoord 监控集群状态。当 QueryNode 负载过高或新节点加入时,协调器会触发Segment 重平衡,将向量数据段(Segment)在不同 QueryNode 之间迁移,从而实现负载均衡。
Q10:你遇到过Milvus的"写入成功但查询不到数据"的问题吗?可能的原因有哪些?
A:
- 未加载 :Collection 未调用
load()将数据加载到 QueryNode 内存中。 - 索引未构建 :数据刚写入,IndexNode 还没完成索引构建(状态不是
Indexed)。 - 一致性延迟 :如果是强一致性要求,可能需要等待
flush操作完成,数据才会从消息队列落盘并可见。
Q11:如果Milvus集群出现查询延迟突然飙升(P99从10ms涨到500ms),你会从哪些维度进行排查?
A:
- 硬件资源:检查 CPU、内存、磁盘 I/O 是否打满。
- 索引状态:检查是否发生了索引退化(如内存不足导致索引未完全加载)。
- 查询参数 :检查
nprobe是否设置过大。 - 过滤条件:是否进行了复杂的标量过滤导致全表扫描。
- 网络:是否存在网络抖动或带宽瓶颈。
⚔️ 第三部分:RAG 实战与选型篇
Q12:在构建企业级RAG系统时,你会选择Milvus还是pgvector?请从数据规模、运维复杂度、混合检索能力三个维度进行对比。
A:
表格
| 维度 | Milvus | pgvector |
|---|---|---|
| 数据规模 | 极强,支持十亿级向量,分布式扩展容易 | 中等,受限于单机 PG 性能,适合中小规模 |
| 运维复杂度 | 较重,依赖组件多(ETCD, MinIO, Pulsar等) | 轻量,若已有 PG 则零成本接入 |
| 混合检索 | 支持标量过滤+向量检索,需配置标量索引 | 极强,直接利用 SQL 的 Join/Where 能力 |
| 适用场景 | 企业级知识库、大规模推荐系统 | 现有 PG 业务的 RAG 升级、中小规模应用 |
Q13:Milvus与Elasticsearch在向量检索方面有何不同?为什么很多大厂会选择"ES+Milvus"的双路召回架构?
A:
- 区别 :Elasticsearch (ES) 擅长关键词匹配 (BM25),准确率高但不懂语义;Milvus 擅长语义匹配,召回率高但可能漏掉精确词。
- 双路召回 :用户 Query -> 同时请求 ES(关键词)和 Milvus(向量) -> 重排序 -> 最终结果。这种架构能兼顾"精确匹配"(如专有名词)和"语义理解"(如 paraphrasing),显著提升 RAG 效果。
Q14:在RAG场景中,如何利用Milvus实现"混合检索"?Milvus的标量字段过滤是在向量检索前还是检索后执行的?
A:
- 实现 :Milvus 支持在搜索时传入
expr(过滤表达式),例如expr="category=='tech' && date > 2023"。 - 执行顺序 :Milvus 2.x 采用了前过滤策略。即先利用标量索引(如倒排索引)筛选出符合条件的 ID 集合,再在这些 ID 中进行向量检索。这比"先搜向量再过滤"效率高得多。
Q15:如何处理长文本或多模态数据的向量化存储?Milvus对稀疏向量的支持情况如何?
A:
- 长文本:通常采用切片(Chunking)后分别向量化,或使用支持长上下文的 Embedding 模型。
- 多模态:使用多模态模型(如 CLIP)将图像/音频转为向量存入。
- 稀疏向量 :Milvus 2.4+ 开始原生支持稀疏向量(Sparse Vector),配合 BM25 算法,可以直接在 Milvus 内部实现关键词检索,从而替代 ES 进行混合检索。
🚀 第四部分:性能优化与避坑篇
Q16:假设你有1亿条768维的向量,单机内存不足以容纳所有索引,你会如何设计Milvus的部署方案?
A:
- 索引选择 :选用 IVF_FLAT 或 IVF_SQ8(量化压缩,减少内存占用)。
- 分片策略 :设置合理的
shards_num,利用分布式 QueryNode 分担负载。 - 磁盘索引 :考虑使用 DiskANN 索引(如果版本支持),将索引驻留在磁盘,通过 SSD 读取,大幅降低内存需求。
Q17:在使用Milvus进行大批量数据插入时,如何优化写入性能?
A:
- Batch Size:增大插入时的 batch size(如 1000-5000 条/次),减少网络交互次数。
- 异步构建:插入时不要同步等待索引构建完成,利用 IndexNode 异步处理。
- 资源预留:确保 DataNode 和 IndexNode 有足够的 CPU/内存资源。
Q18:在使用Milvus进行标量字段过滤时,为什么有时会出现QPS大幅下降的情况?如何避免"全表扫描"?
A:
- 原因 :如果对某个字段(如
tags)进行过滤,但该字段没有建立标量索引 (enable_analyzer=False或未配置),Milvus 会退化为全表扫描(Brute Force),导致 QPS 暴跌。 - 解决:确保用于过滤的字段在 Schema 中正确配置了索引(如倒排索引)。
Q19:如果在Schema设计时,向量维度设置错误(如实际插入向量维度与Schema定义不符),会导致什么后果?如何修复?
A:
- 后果:SDK 会直接报错,或者导致数据损坏/无法检索。
- 修复 :维度是不可变的。通常需要重建集合(Collection),修改 Schema 中的维度定义,然后重新导入数据。