ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

千亿级AI知识库架构实战:腾讯云ES如何支撑RAG混合检索与分片优化

千亿级AI知识库架构实战:腾讯云ES如何支撑RAG混合检索与分片优化 1. 千亿级知识库到底难在哪从ima的架构选择说起第一次看到“千亿级AI知识库”这个量级的时候我脑子里冒出来的第一个问题不是“用什么模型”而是“数据怎么存、怎么查、怎么在用户等答案的那几秒里把最相关的片段捞出来”。ima这个产品做的事情本质上是把海量文档、对话、笔记、网页内容变成可被语义检索的知识资产再通过RAG检索增强生成把命中的内容喂给大模型让回答有据可依。听起来链路不长但一旦数据量从百万级爬到千亿级每一个环节都会从“能跑”变成“能不能扛住”。我接触过不少团队做知识库起步阶段基本都是“先上个向量库再说”数据量小的时候确实顺风顺水几万条向量、几百个并发随便一台机器都能撑。但到了千万级、亿级问题就开始集中爆发写入变慢、检索延迟抖动、召回率下降、内存吃紧、集群扩容之后分片分布不均。ima选择腾讯云ES作为底层检索底座这个决策本身就值得拆开讲——它不是简单地“用ES存向量”而是把全文检索、向量检索、过滤条件、聚合分析这几件事放在同一个引擎里做避免了多套系统之间数据同步带来的延迟和一致性问题。这篇文章我想聊的不是“ES怎么装”而是千亿级知识库在架构层面真正要解决的几个核心矛盾写入吞吐和检索延迟怎么平衡、向量维度和索引结构怎么选、分片策略怎么设计才能让扩容不翻车、RAG链路里检索层和生成层怎么解耦。适合正在做知识库选型、已经踩过向量库扩容坑、或者想搞清楚“为什么大厂知识库不只用向量库”的读者。我会尽量把每个决策背后的“为什么”讲透而不是只给一个结论。先说一个反直觉的点千亿级知识库的瓶颈往往不在向量检索本身而在数据摄入和索引构建阶段。向量检索再快如果文档解析、分块、向量化、写入这条流水线堵住了整个系统就是不可用的。ima的架构实践里腾讯云ES承担的不只是“查”的角色还包括了写入链路的缓冲和索引生命周期的管理。这一点在后面讲分片和写入优化的时候会展开。2. 为什么是腾讯云ES而不是纯向量数据库2.1 纯向量库在知识库场景下的三个硬伤很多团队第一反应是选一个专门的向量数据库理由很直接向量检索快、API简单、上手成本低。我在早期项目里也这么干过但做到一定规模之后三个问题几乎必然出现。第一个是过滤条件下的检索效率断崖式下跌。知识库检索很少是“纯语义相似度排序”用户往往带着条件来查只要某个知识库的、只要某个时间范围之后的、只要某个文档类型的。纯向量库做“先向量检索再过滤”会导致大量无效候选被丢弃召回率直接崩做“先过滤再向量检索”又要求过滤字段和向量索引深度耦合很多向量库在这块的支持并不成熟。ES的做法是把结构化过滤和向量检索放在同一个查询计划里filter上下文可以走倒排索引快速缩小候选集再在缩小后的集合上做向量近邻搜索这个差异在千万级以上数据量时非常明显。第二个是全文检索和语义检索的融合需求。RAG的召回质量很大程度上取决于“能不能同时利用关键词精确匹配和语义相似匹配”。用户搜一个专有名词、一个错误码、一个人名关键词匹配往往比向量更准用户问一个模糊的、口语化的问题向量检索更合适。纯向量库做不了BM25纯全文检索引擎做不了语义而ES同时支持两者可以在一次查询里做混合打分。ima的知识库场景里这两种检索模式是并存的不是二选一。第三个是运维生态的成熟度。向量数据库这几年冒出来很多但真正经过大规模生产验证、有完整监控指标、有成熟的扩容和故障恢复方案的并不多。ES在这个领域积累了十几年分片分配、副本恢复、慢查询日志、线程池监控这些能力是现成的。腾讯云ES在此基础上做了托管和内核优化对于不想自己维护集群的团队来说省掉的是大量半夜起来处理节点掉线的时间。2.2 腾讯云ES在ima架构里承担的具体角色从架构分层来看ima的知识库链路大致可以拆成四层接入层负责文档上传和解析处理层负责分块和向量化存储检索层由腾讯云ES承担生成层由大模型完成答案组织。ES在这一层里同时做三件事向量存储与近邻检索用dense_vector字段类型存储文档块的向量表示通过HNSW或IVF索引加速近邻搜索。全文索引与BM25打分对文档块的原始文本建立倒排索引支持关键词精确匹配和短语查询。元数据过滤与聚合文档来源、知识库归属、时间戳、文档类型等字段作为keyword或date类型存储支持高效的filter和聚合。这三件事放在一个引擎里最大的好处是一次查询就能完成召回不需要在多个系统之间做结果合并和去重。我见过一些架构是“向量库召回一批 ES召回一批 应用层做RRF融合”这种方案不是不行但多了一次网络往返、多了一套数据同步逻辑、多了一个一致性维护点。数据量小的时候无所谓千亿级的时候每多一个环节都是故障面。提示选型时不要只看“向量检索 benchmark 谁快”要看你的查询里有多少比例带过滤条件、有多少比例需要关键词兜底。如果这两个比例都不低纯向量库的短板会很快暴露。2.3 向量维度与索引类型的选择逻辑ima场景下文档块的向量维度通常在768到1024之间这个区间是当前主流embedding模型的常见输出维度。维度选择不是越高越好维度越高单条向量占用的内存和磁盘越大HNSW索引的构建时间和查询时的距离计算开销也越大。768维在召回质量和资源消耗之间是一个比较平衡的点1024维在语义区分度要求更高的场景下更合适。索引类型方面ES支持HNSW和IVF两种近似近邻算法。HNSW的查询延迟更低、召回率更高但内存占用大、构建慢IVF的内存占用小、构建快但查询时需要扫描更多候选。千亿级场景下内存是比磁盘更稀缺的资源所以实际选型往往要在HNSW的m参数和ef_construction参数上做权衡或者对冷热数据分层——热数据用HNSW保证延迟冷数据用IVF或者更低精度的索引降低内存压力。这里有一个容易被忽略的点向量索引的构建是在写入时完成的写入吞吐和索引质量之间存在天然矛盾。HNSW的ef_construction越大索引质量越好但构建越慢。ima在写入链路上做了批量缓冲把单条写入攒成批量请求既提高了吞吐也让索引构建的摊销成本更低。这个批量大小的选择很关键后面讲写入优化时会具体说。3. 千亿级数据下的分片策略与写入链路设计3.1 分片数量不是拍脑袋定的ES的分片策略是千亿级场景下最容易翻车的地方。我见过太多团队一开始设了十几个分片数据涨到百亿级之后发现单个分片太大查询时线程池被打满也见过分片设了几百个结果集群元数据膨胀、主节点压力过大、每次创建索引都要等半天。分片数量的核心约束是单个分片的大小和单分片的文档数。业界比较共识的经验值是单个分片控制在30GB到50GB之间单分片文档数控制在千万级以内。按这个反推千亿级文档、每条约1KB原始文本加向量数据总数据量在TB级别分片数量大概在几十到上百个这个量级。但这不是一个固定公式因为向量字段会显著增加单条文档的存储开销实际计算要把向量维度乘上4字节float32再乘上文档数。ima的做法是按知识库维度做路由不同知识库的数据落在不同的索引里每个索引再根据数据量动态调整分片数。这样做的好处是查询时可以精确路由到目标索引避免在全量数据上做无谓的扫描同时单个知识库的扩容不会影响其他知识库。3.2 写入链路的缓冲与背压千亿级知识库的写入不是“用户传一个文档就写一条”而是批量摄入、异步处理。ima的写入链路大致是这样的文档上传后先进入消息队列解析和分块服务从队列消费把文档切成合适大小的块调用embedding服务生成向量然后批量写入ES。这条链路里有两个关键设计。第一个是批量写入的大小。单条写入ES的开销主要在网络往返和索引刷新上批量写入可以显著提高吞吐。但批量太大又会导致单次请求超时、内存占用过高。实测下来每批500到1000条文档、每批总大小控制在5MB到10MB之间是一个比较稳的区间。腾讯云ES的bulk接口对这个量级的批量请求处理得比较成熟。第二个是背压机制。当ES写入变慢时如果上游继续无节制地往队列里塞数据队列会堆积、内存会爆。ima在消费端做了速率控制根据ES的写入延迟和线程池队列深度动态调整消费速率。这个逻辑不复杂但很多团队在初期会忽略等到线上出问题才补。3.3 怎么判断写入慢是磁盘问题还是其他问题这是一个非常实际的运维问题。ES写入变慢的原因可能有很多磁盘IO瓶颈、CPU打满、线程池队列积压、分片分配不均、merge压力过大。判断的顺序我一般是这样的排查项观察指标可能原因磁盘IOiostat的%util、await磁盘饱和写入排队CPU节点CPU使用率、load average索引构建或merge消耗过多CPU线程池write线程池的queue和rejected写入请求超过处理能力分片分布各节点分片数、单分片大小热点分片导致单节点压力过大Mergemerge线程池、segment数量频繁refresh导致小segment过多磁盘问题的典型特征是iostat的%util持续接近100%、await明显升高同时CPU和线程池指标相对正常。如果磁盘没问题但写入还是慢大概率是分片分布不均或者merge压力。腾讯云ES的控制台提供了这些指标的监控视图不用自己搭Prometheus也能看到。注意不要一看到写入慢就加节点。如果是分片分布不均导致的加节点反而会让分片重新分配短期内写入更慢。先定位根因再动手。4. RAG链路里检索层和生成层的配合细节4.1 召回阶段混合检索怎么配比RAG的召回质量直接决定最终回答的质量。ima的检索层用的是向量检索加全文检索的混合模式两者各自召回一批候选然后做融合排序。融合的方式有几种RRF倒数排名融合不依赖分数归一化实现简单加权分数融合需要把BM25分数和向量相似度分数归一化到同一量纲调参成本更高但可控性更强。实际配比上向量召回和全文召回的候选数通常各取top 50到top 100融合后取top 10到top 20送给生成层。候选数太少会漏掉相关文档太多会增加生成层的上下文长度和推理成本。这个数字不是固定的要根据知识库的文档密度和查询类型动态调整。有一个容易被忽略的细节向量检索的相似度阈值。不是所有查询都能找到高相关度的文档如果强行把低相似度的结果喂给模型反而会引入噪声。ima在检索层设了一个最低相似度阈值低于阈值的候选直接丢弃宁可让模型说“没有找到相关信息”也不让它基于不相关内容胡编。4.2 分块策略对召回的影响文档分块是RAG链路里最容易被低估的环节。块切得太大向量表示会稀释检索时匹配精度下降块切得太小上下文不完整模型拿到碎片化信息也组织不出好答案。ima的分块策略是按语义边界切分同时控制块大小在合理区间。具体做法是先用规则做粗切按段落、按标题层级再用语义相似度做细调把语义连贯的句子合并成一个块。块大小通常控制在256到512个token之间这个区间在检索精度和上下文完整性之间比较平衡。对于表格、代码块这类特殊内容分块策略要单独处理。表格如果按行切分会丢失表头信息代码如果按行切分会破坏语法结构。ima对这类内容做了特殊标记在检索时优先保证完整性。4.3 生成层的上下文组织检索层召回top K个文档块之后怎么组织这些块送给模型也是有讲究的。最简单的做法是按相似度排序拼接但这样会导致相似度最高的块在上下文最前面模型对中间和末尾的内容注意力下降。ima的做法是把最相关的块放在上下文的首尾两端中间放次相关的块利用模型对首尾位置注意力更强的特性提升关键信息的利用率。另外每个块前面会加上来源标记文档标题、章节路径让模型知道这段内容来自哪里生成答案时可以引用来源。这个细节对知识库产品的可信度很重要用户看到答案能追溯到原文才会信任这个系统。5. 向量检索性能调优的实操经验5.1 HNSW参数怎么调HNSW的核心参数有三个m每个节点的邻居数、ef_construction构建时的候选队列大小、ef_search查询时的候选队列大小。m越大索引质量越高但内存占用和构建时间也越大ef_construction越大索引构建越慢但质量越好ef_search越大查询召回率越高但延迟越大。我的经验值是m取16到32之间ef_construction取100到200之间ef_search根据延迟要求动态调整。千亿级场景下m取16是比较稳妥的选择内存占用可控如果召回率不达标优先调大ef_search而不是m因为ef_search只影响查询延迟不影响索引构建和内存。腾讯云ES对HNSW做了一些内核层面的优化在批量构建和查询调度上有改进。实际测试下来同样的参数配置腾讯云ES的查询延迟比自建集群低20%到30%这个差异在高峰期比较明显。5.2 冷热数据分层千亿级知识库里真正被频繁检索的数据可能只占20%到30%大部分数据是冷数据偶尔被查到一次。如果所有数据都用同样的索引配置内存会被冷数据占满热数据的查询性能反而下降。ima的做法是按访问频率做冷热分层。热数据用HNSW索引保证低延迟冷数据用IVF索引或者更低的索引精度降低内存占用。冷热之间的迁移根据访问统计自动触发不需要人工干预。这个策略在千亿级场景下能显著降低内存成本同时保证热数据的查询体验。5.3 查询时的并发控制ES的向量检索是CPU密集型操作高并发查询时线程池很容易被打满。ima在查询层做了并发限流和优先级队列核心知识库的查询走高优先级队列保证延迟非核心查询走低优先级队列可以容忍一定的排队。同时设置了单节点的最大并发查询数超过阈值的请求直接拒绝避免雪崩。这个策略听起来简单但实际落地时需要根据业务场景定义“什么是核心查询”。ima的做法是按知识库的SLA等级划分付费用户的知识库优先级更高免费用户的查询在高峰期可以排队。这个决策涉及产品层面不是纯技术问题。6. 踩过的坑和实际运维中的注意事项6.1 分片分配不均导致的查询热点早期我们遇到过一个问题集群有几十个分片但查询延迟忽高忽低。排查后发现是分片分配不均部分节点承载了过多分片查询时这些节点的线程池先被打满。ES的默认分片分配策略是基于分片数量的不考虑分片实际大小和查询负载。解决办法是用分片分配过滤和感知策略把大分片分散到不同节点同时监控各节点的查询延迟发现热点及时调整。6.2 向量索引构建阻塞写入HNSW索引的构建是在写入时同步完成的如果批量写入的向量数据量很大索引构建会占用大量CPU和内存导致写入线程池排队。ima的解决办法是把索引构建和写入解耦写入时先存原始向量索引构建异步进行。腾讯云ES支持这种异步索引构建模式代价是索引构建完成前查询走暴力扫描延迟会高一些但写入吞吐有保障。6.3 召回率不达标时的排查顺序召回率下降是RAG系统最常见的问题。我的排查顺序是先看分块策略有没有问题再看embedding模型有没有换过再看检索参数有没有被改过最后看数据分布有没有变化。分块策略的问题最隐蔽因为块大小变化不会报错只会让检索结果慢慢变差。embedding模型换版本会导致向量空间变化旧向量和新向量不兼容必须全量重建索引。检索参数被改的情况在多人协作的团队里很常见建议把参数配置纳入版本管理。6.4 监控指标要盯哪些千亿级知识库的监控不能只看集群健康状态。我日常盯的指标包括查询延迟的P99和P999、写入延迟的P99、线程池的queue和rejected、各节点的CPU和内存、磁盘IO的util和await、merge线程池的积压情况、分片分布均衡度。这些指标在腾讯云ES的控制台都有现成的视图设置好告警阈值之后基本不用天天盯着。提示P99延迟比平均延迟更能反映用户体验。平均延迟100ms但P99是2秒的系统用户会明显感觉到卡顿。7. 一些关于知识库架构的个人体会做知识库这几年我最大的体会是架构决策没有绝对的对错只有适不适合当前的业务阶段。ima选择腾讯云ES作为底座是因为它的业务场景需要全文检索和向量检索的融合、需要成熟的运维生态、需要托管服务来降低运维成本。如果你的场景是纯语义检索、数据量在千万级以内、团队有足够的运维能力纯向量库可能是更轻量的选择。另一个体会是RAG系统的效果上限取决于数据质量不取决于模型。我见过太多团队花大量时间调模型、调prompt但文档解析得一塌糊涂、分块切得乱七八糟、元数据缺失严重。这些基础工作做不好再好的模型也救不回来。ima在数据摄入链路上投入的资源远比在生成层调优上投入的多这个比例是对的。最后说一个实际的小技巧在检索层加一个“查询改写”步骤。用户的原始查询往往口语化、有歧义直接拿去检索效果不好。ima的做法是先用一个小模型把用户查询改写成更适合检索的形式再走混合检索。这个步骤增加了一点延迟但召回率的提升很明显尤其是在用户查询很短或者很模糊的时候。知识库这个方向还在快速演进Agentic RAG、GraphRAG这些新范式也在不断出现。但不管上层怎么变底层的检索层始终要解决“海量数据下快速找到相关内容”这个核心问题。腾讯云ES在这个问题上的积累是ima选择它的根本原因。
返回列表