要撑起一个千亿级的AI知识库,技术选型和架构设计都不是拍脑袋决定的。这篇文章我准备围绕ima在腾讯云ES上的落地实践,把从集群规划、索引设计、写入链路到检索调优的完整思路梳理一遍。其中涉及的参数、方案、踩坑记录,都是我们实际跑过、验证过的,希望能给同样在做AI知识库或大规模RAG系统的团队一些参考。
先说清楚这个项目的边界。ima是腾讯推出的智能工作台产品,核心能力之一是帮助用户沉淀个人和团队知识,再通过AI语义检索把知识“用起来”。底层一旦挂了海量知识文档,检索性能和准确性就会出现明显拐点。我们当时面临的核心问题可以概括成三个:
- 数据规模大:知识文档总量达到千亿级别,且还在持续增长。
- 检索要求高:要支持关键词、语义、向量混合检索,且响应速度不能因为数据规模变大而明显劣化。
- 成本敏感:全量数据用纯内存或高规格SSD扛,成本会失控,必须做分层存储和冷热分离。
在做技术选型时,我们对Elasticsearch和腾讯云ES做过详细对比。自建ES在运维成本和扩展性上问题突出,千亿级分片的管理、滚动升级、故障自愈这些事,自己做等于再造一个运维中台。腾讯云ES天然托管了这部分能力,而且兼容原生ES生态,我们原有的检索代码几乎零改造就能跑上去。更重要的是它对超大规模集群的横向扩展有成熟方案,实测性能也符合预期。所以最终选择了“Elasticsearch + 腾讯云ES托管”的组合作为知识库检索内核。
1. 项目背景与核心问题拆解
1.1 千亿级知识库意味着什么
千亿级这个量级,不只是“文档数量多”这么简单。它至少带来三重挑战:
第一,存储成本高。每一篇文档除了原文,还要处理成可检索的文本块、向量、元数据标签,同一份内容可能有多个副本。存储膨胀倍数通常在3到8倍之间。我们用1TB原始数据做测试,包含向量和倒排索引后,占用空间约为4.2TB,这还没算副本。如果不做冷热分离,成本完全扛不住。
第二,写入吞吐压力大。知识库里的数据不是一次性导入完就静止了,它有持续的新增、更新、删除。千亿级文档的增量更新如果按天计算,每天可能会有数亿文档的写入规模。这要求写入链路必须是异步批量化的,绝不能同步逐条写ES。
第三,检索时效性要求高。AI知识库检索背后往往连着大模型生成链路,用户侧能接受的检索P99响应时间大概在300到500毫秒以内。这需要做query理解、多路召回、粗排精排,每一层都会消耗时间预算。
当时我们还有一个容易被忽视的问题:文档去重。千亿级数据里,重复文档、近似重复文档非常多。如果不在源头做去重,ES里存的有一大部分是垃圾数据,既浪费存储又拉低检索精度。去重这件事必须在进入ES之前解决,不能依赖ES本身。
1.2 为什么最终锁定Elasticsearch而不是其他存储
我也听到过不少质疑,比如“千亿级数据为什么不用ClickHouse?”“为什么不用Milvus做向量库?”“干脆上HBase算了”。这些质疑都有道理,但结合AI知识库的实际检索特征,ES仍然是最合适的底座:
- 知识库检索是典型的“先召回后排序”场景,关键词命中、向量相似度、过滤条件需要在一个框架里统一处理。ES的DSL天然支持布尔组合、过滤、聚合、向量检索,这是其他系统很难整体替代的。
- 向量检索已经深度集成到ES内核中。从ES 8.x开始,dense_vector类型配合HNSW算法,能提供不错的ANN召回能力。ima的场景不是纯向量检索,而是“关键词+向量”混合检索,使用ES可以避免引入额外向量组件,减少数据同步链路,也大幅降低架构复杂度。
- ES的索引和分片机制,天然适合文档型数据,缓存的淘汰策略、段合并策略、查询并发模型等也都经过长时间打磨。相比其他存储系统,ES对于“文档型数据+复杂查询”的支持更成熟。
腾讯云ES在托管层面又解决了几个顽疾:集群版本升级、滚动重启、节点故障自动恢复、冷热节点分离、索引生命周期管理。这些能力在自建ES时都要花大量时间去维护,托管服务把这些变成了开箱即用的功能。
1.3 站在业务角度看架构演进
架构设计从来不是为了技术炫技。ima的知识库有一个明显特征:场景以团队协作为主,一个团队的知识库可能只有几万个文档,但所有团队加在一起就是千亿规模。这决定了我们不能按“一个团队一个索引”的方式来设计,否则索引数量会爆炸。
从业务视角看,我们需要的是一个多租户、可伸缩、具备多层缓存能力的架构。用户查询时先经过网关层识别租户,再进入知识库路由层定位对应的索引组,然后才到ES集群执行检索。这一层路由在早期数据量小时不需要,但到了千亿级,索引数量怎么组织就成了一个独立的架构问题。
我们的核心经验是:架构设计不能只盯着ES本身,要从“数据接入、索引组织、检索链路、成本控制”四个维度来规划。
2. 集群规划与分片设计
2.1 集群规格的选择逻辑
腾讯云ES的集群规划,第一步是定节点规格和数据盘。我们的实践思路是这样的:
- 数据分片数:以每个分片30GB到50GB为基准。分片太小会导致查询扇出严重,分片太大则移动和恢复耗时长。千亿级数据量,总存储预估在4PB左右,分片总数控制在8万到12万个之间。
- 节点规格:选择32核64GB的节点规格作为数据节点主力。这里有一个性价比岔路口,计算密集型和存储密集型要分开,我们专门设置了热数据节点和冷数据节点两种规格。
- 热节点:使用高IOPS SSD,承载最近90天的活跃数据和向量索引。向量检索对内存和CPU的开销远高于普通倒排索引,所以热节点要求内存不低于64GB。
- 温节点:使用普通SSD,承载历史数据中仍有较高访问频率的部分,允许查询性能略有下降但存储成本更低。
- 冷节点:使用大容量HDD,存放超过180天、极少访问的归档数据。冷节点不参与实时查询,主要作为备份和合规留存。
规格选定后,一定要通过真实数据做压测确认,而不是拍脑袋。我们第一次压测时发现,32核64GB节点扛不住四个500GB分片的并发向量检索,原因在于HNSW图遍历时的CPU消耗被低估了。后来调整为“单节点最多2个热分片参与向量检索”,同时把热节点CPU规格提升到48核,问题才彻底解决。
2.2 分片规划背后的数学
分片数不是随意定的,它有一个固定公式逻辑:
总分片数 = 总数据量 / 单分片目标容量 单节点分片数上限 = (节点内存 - 预留内存) / 单分片内存开销以我们某个索引组为例,数据量约2.4TB,副本数1,单分片容量目标40GB,得到总分片数约120个。如果每个节点最多承载30个分片,那这个索引组至少需要4个数据节点。这里要注意,ES的分片数一旦设定,后期调整成本极高,必须一次性规划到位。
我强烈建议,分片规划时给未来半年的增长留出30%余量。我们曾经因为分片数算得太精准,半年后数据自然增长后不得不做一次全量reindex,整个过程持续了几天,而且查询抖动明显。如果当时多预留30%,这场事故完全可以避免。
2.3 索引模板与租户隔离策略
ima是多租户体系,但我们在ES层没有采用“一租户一索引”的方案。原因是索引数量过多后,集群的元数据管理、分片分布、缓存命中率都会劣化。实测发现,当集群中的索引数量超过3万个,集群状态更新和节点心跳的开销会明显上升。
我们的解法是“索引模板 + 分片路由 + 租户标识字段”的混合设计:
- 每个业务线使用一套索引模板,按时间滚动。
- 租户标识不是索引维度,而是文档的字段维度。所有检索都会携带租户ID过滤条件,ES底层通过filter缓存把租户过滤开销降到极低。
- 对于大租户(数据量超过500GB),单独拆分索引组;小租户共享索引组,控制索引总量在一个健康范围。
这样做还能顺带解决热点问题。如果某个大租户突然有高并发查询,它独占的索引组不会被其他租户流量干扰;而小租户因为数据量小、分片少,共享索引组也足够支撑日常并发。
3. 千亿级索引设计实战
3.1 映射设计的几个关键取舍
ES的mapping设计直接决定了检索效果和存储效率,我们在实战中总结出几条硬经验:
文档主字段用keyword类型。知识文档的ID通常是业务生成的唯一标识,不要使用默认的text类型,避免不必要的分词和倒排存储,节省30%以上的索引空间。
需要分词的字段才用text类型,并且指定分词器。ima场景下,中文内容居多,我们使用ik_max_word分词器配合自定义停用词表。这里有一个容易被忽视的细节,ik_max_word分词粒度较细,适合索引阶段;搜索阶段建议用ik_smart,保证召回更精准且耗时更短。
向量字段使用dense_vector类型,并指定HNSW参数。千亿级数据下,HNSW的m参数(邻居数量)和ef_construction参数对召回率和内存开销影响很大。我们最终定在m=32,ef_construction=128。再高召回率提升有限,但内存开销和构建时间成倍增加。
禁用不需要的字段的doc_values。如果某个字段只是用来过滤但不需要排序聚合,可以关闭doc_values,节省磁盘空间。我们的元数据字段里有大量标签字段,统一设置为"doc_values": false,整体磁盘占用下降了约18%。
3.2 嵌套结构与扁平化之争
知识文档天然有层级结构,例如一篇文档包含多个章节,每个章节包含多个段落。刚开始我们尝试用ES的nested类型来建模,结果发现查询性能很差,尤其是千亿级规模下,nested文档的父文档和子文档关联查询开销极大。
最终我们选择了扁平化方案:将文档拆分为“段落块”,每个段落块作为一个独立文档写入ES。每个文档包含区块ID、所属文档ID、文档标题、正文片段、向量、租户ID等字段。查询时通过文档ID聚合返回整篇文档的相关段落。
扁平化之后有两个优势:
- 检索维度直接落在段落块上,向量检索和关键词检索共用一个文档集合,逻辑简单清晰。
- 更新和删除粒度更细。如果某个段落内容更新,只需要重新索引该段落,而不需要整篇文档重建。
但这里也有一个代价,就是检索结果需要做一次聚合归并。我们在检索服务里加了一层“按文档ID去重合并”的逻辑,过滤掉同一文档的冗余段落,保证用户最终看到的是一条知识而不是一堆碎片。
3.3 生命周期管理:数据分级是成本杀手
数据不分级,千亿级规模下存储费用会直接击穿预算。腾讯云ES提供了索引生命周期管理(ILM)能力,我们结合业务访问规律做了三级生命周期策略:
- 索引创建后默认进入热节点,90天内保持最高性能。
- 90天后自动迁移到温节点,保留基础性能但存储单价更低。
- 180天后迁移到冷节点,并关闭副本,只保留主分片数据,牺牲高可用换取成本。
实际操作中还有一个细节:ILM的rollover条件要设置合理。我们的策略是“单索引超过600GB或写入超过7天即触发滚动”,避免单个索引过大,降低分片热点和段合并压力。另外,冷节点数据虽然不参与实时查询,但我们保留了一个“归档恢复”按钮,用户可以手动触发恢复任务,把特定索引从冷节点提升到热节点,满足偶发回溯需求。
4. 数据写入链路的架构与调优
4.1 异步批量写入的完整链路
ES的写入瓶颈经常不在ES本身,而在写入链路的设计。早期测试时我们逐条同步调用ES接口,结果压测2000条文档就把集群写入队列打满,ES返回reject。后来我们重构为异步批量写入架构,链路变成:
数据接入 -> 消息队列(Kafka)-> 批处理服务 -> ES bulk请求 -> 写入结果回执数据源产生的变更先进入Kafka,批处理服务按固定窗口攒批,攒满500条或超过3秒即触发一次bulk写入。采用这个方案后,单节点写入TPS从最初的几百提升到接近1.2万,集群整体写入吞吐提升了两个数量级。
批处理服务还要承担一个关键职责:数据清洗与去重。我们在写入前做MD5指纹比对,指纹库落在Redis里,发现重复文档直接丢弃。这个策略让ES里实际存储的文档数比接入文档数少了接近40%,效果非常显著。
4.2 bulk写入的参数调教
bulk不是调得越大越好,它受限于ES的HTTP请求体大小和内存分配。我们的实测数据如下:
- bulk大小在5MB到15MB之间时,写入性能表现最优。
- 超过25MB后,ES会有较高的解析失败率和内存压力,反而拉低性能。
- 单批次文档数量最好控制在500到1000条之间,超过1500条后,单次请求耗时线性上升,不利于平均延迟控制。
还要设置合理的写入并发。我们最初并发设置为16,结果把ES写入线程池打满了;后来改为8,性能反而上升,原因是减少了线程上下文切换和内存竞争。压测时要从低并发开始逐步上调,观察ES的thread_pool指标,找到拐点后固定下来,而不是盲目拉高。
另外,bulk失败一定要有重试机制,但要带退避。我们采用的是“3次重试 + 指数退避 + 失败数据进死信队列”的策略。死信队列里的数据可以人工介入修复,避免数据丢失。
4.3 避免写入拒绝的实操方案
千亿级场景下,ES的写入拒绝几乎是必然事件,关键是拒绝后怎么办。我们的经验有几条:
一是设置合理的队列大小。ES默认的写入队列大小是200,对大规模写入来说偏小。我们将写入线程池队列调整到800,同时配合后续的批量削峰,整体拒绝率从5%降到0.1%以下。
二是把bulk请求打散到不同节点。ES的HTTP请求如果都打到协调节点,协调节点会成为瓶颈。我们在客户端使用轮询策略,让bulk请求均匀分发到集群内多个节点,降低单点压力。
三是对写入做限速。消息队列积压时,批处理服务要主动降低消费速率,而不是继续全速消费。我们采用“动态反馈”机制,定时读取ES的写入队列占用率,如果超过70%,就降低Kafka消费速率;低于30%则逐步恢复。这套机制保证集群永远工作在健康水位。
5. 查询链路设计与性能优化
5.1 查询路径的每一跳都是优化机会
用户一次检索请求的完整路径如下:
用户请求 -> API网关 -> 检索服务 -> 知识库路由 -> ES查询 -> 结果后处理 -> 返回每一跳都有自己的优化空间。API网关层做了租户鉴权和流控;检索服务层做了query改写与意图识别;知识库路由层负责找到具体索引组;ES查询则在最终数据层完成关键词、向量和过滤条件的混合检索。
query改写常常被低估。用户输入的原始query往往语义不完整,比如“昨天的文档发我一下”,直接拿全句去检索效果很差。我们通过大模型对query做意图识别和关键词抽取,选择检索知识库时只使用“文档”作为核心实体词,再配合租户、时间等结构化过滤条件,召回率和准确率都会明显变好。这一步在千亿级规模下比在中小数据集上收益更显著。
5.2 多路召回与二次排序
AI知识库的检索不能只依赖单一召回通道。我们的实践是采用三路召回:
- 倒排索引召回:使用BM25算法做关键词匹配。
- 向量召回:使用HNSW近似最近邻做语义匹配。
- 过滤召回:基于知识标签和时间范围做结构化检索。
三路召回结果合并后,进入一个轻量级的排序层。排序层根据业务规则和基础特征做粗排,比如关键词命中位置、向量相似度、文档权威度等。粗排后的Top 50结果再交给精排模型或大模型进行答案生成。
倒排召回和向量召回有一个权重配比问题。最初我们使用固定权重,效果不理想。后来改为“按query自适应权重”,具体做法是:如果query中包含明确的专有名词,提高关键词召回权重;如果query是抽象问题描述,则提高向量召回权重。这套自适应逻辑上线后,检索满意度的提升幅度非常明显。
5.3 缓存体系:别让所有流量都打到ES
千亿级数据量下,即便ES性能再好,也不能让所有重复流量都穿透到ES。我们的缓存体系分为两层:
- 第一层是检索服务本地内存缓存,使用LRU策略,缓存最近5分钟的高频查询结果,TTL 300秒。这层缓存命中率约为35%。
- 第二层是分布式缓存Redis Cluster,缓存内容为ES返回的Top 10结果集合,TTL 1800秒。这层缓存命中率约为25%。
两层缓存加起来,大约60%的检索请求不会穿透到ES。这不仅降低了ES的QPS压力,还显著改善了用户侧的平均响应时间。我们采用双缓存还带来一个额外收益:当ES集群因版本升级或故障切换暂时不可用时,缓存仍然能够支撑一部分读流量,避免服务完全不可用。
缓存更新也是一个要仔细处理的问题。我们的策略是:当底层文档发生变更时,通过消息队列通知缓存失效;如果文档变更量较大,则直接清空相关索引组的Redis缓存,宁可集中穿透一次,也要保证缓存里的数据不是脏数据。
6. 性能压测与调优实录
6.1 压测方案怎么设计才靠谱
压测不能泛泛地拿几个接口跑一下,要看真实的场景混合比。我们把压测流量分成三类:
- 咨询类检索(高频):关键词查询,短语查询,QPS占比70%。
- 语义检索(中频):向量查询,QPS占比20%。
- 管理类操作(低频):文档删除、批量导入,QPS占比10%。
压测工具选用JMeter与自研压测脚本结合。压测过程分为四个阶段:单节点压测、单索引组压测、全集群压测、极限压测。前两阶段用来发现单点性能和索引设计问题,第三阶段评估整体架构,第四阶段找到集群的性能拐点。
有一个容易被忽视的点:压测数据必须模拟真实数据分布。如果压测时数据均匀分布,而真实场景存在明显热点,压测结果就没有参考价值。我们在压测索引里人为制造了20%的热点文档,让压测更贴近线上情况。
6.2 我们碰到过的三个典型性能瓶颈
第一个瓶颈是协调节点CPU打满。千亿级数据下,一个查询要遍历多个分片,协调节点需要合并大量结果集。我们发现当并发超过200时,协调节点CPU先于数据节点打满。解决方法是:在网关层增加请求合并,把相同或相似的查询合并成一次ES请求;同时为协调节点单独扩容CPU。这个方法实施后,集群整体支撑并发从200提升到600。
第二个瓶颈是无脑使用通配符查询。知识库场景里,用户经常输入不完整的词,导致前端生成类似title:关键词的查询,这种查询无法利用倒排索引,必须全表扫描。我们在检索服务层做了标准化:对必须使用通配符的场景,限定扫描范围为最近30天的索引,并对超时查询设置降级策略。
第三个瓶颈是深度分页。用户查看检索结果时,如果翻到第100页之后,传统的from+size方式会导致ES查询耗时显著上升。我们改用search_after配合游标的方式,同时限制最大翻页深度为1000条。对确实需要深度翻页的管理端场景,则改用scroll接口,避免线上高并发检索链路被深度分页拖垮。
6.3 查询延迟的尖刺治理
在千亿级场景里,平均延迟往往看起来很健康,但P99延迟会频繁出现尖刺。我们排查后发现尖刺的几个主要来源:
- 段合并:大分片在做段合并时,CPU和IO资源被大量占用,查询延迟瞬间上升。
- 冷热数据迁移:ILM在做数据迁移时,大量文档从热节点搬到冷节点,对集群产生额外压力。
- 垃圾回收:JVM Full GC时,节点短暂失去响应。
针对这些尖刺,我们逐一做了治理。段合并方面,在业务低峰期手动触发force merge,将小块段合并成大段,减少自动合并频率。冷热迁移方面,把ILM迁移动作限制在凌晨2点到5点,并且限制迁移速率。JVM GC方面,设置G1GC参数,并确保节点堆内存不超过物理内存的50%,预留足够空间给OS page cache。
治理之后,ES查询P99延迟从偶尔超过800毫秒降到稳定在300毫秒左右,效果非常显著。
7. 腾讯云ES运维实践与稳定性保障
7.1 监控指标到底要看哪些
腾讯云ES控制台自带监控面板,但我们发现只依赖默认监控是不够的,需要自定义一套业务侧的监控指标。我们最终形成一套核心监控列表:
- 集群健康状态:绿灯、黄灯、红灯的切换要能自动告警。
- 节点CPU使用率:持续超过70%要关注,超过85%要立即处理。
- 写入队列占用率:超过70%说明写入压力过大。
- 查询耗时分布:按索引组分类,观察P50、P95、P99变化。
- 段合并速率:如果持续高位,需要排查是否需要force merge。
- 缓存命中率:本地缓存和Redis缓存命中率如果连续下跌,要检查缓存失效策略是否出了问题。
监控不止是看数字,更要配置告警。我们的告警规则是分级通知:预警级别发消息给运维群,严重级别同时电话通知责任人。告警阈值要基于压测结果和历史数据设定,避免频繁误报导致告警疲劳。
7.2 节点故障和分片恢复
ES节点故障是千亿级集群中的常态事件,关键在于故障恢复的速度。腾讯云ES托管了节点替换和分片恢复流程,但我们在业务侧也要做配合。
有一次,集群中一个数据节点物理机故障,系统自动替换新节点后,开始大规模分片恢复。由于恢复流量过大,导致集群查询性能明显下降。后来我们采取了一个更稳妥的策略:分片恢复限流。恢复速率限制在正常水平的50%,优先恢复索引组中的热数据索引,冷数据索引放在后面。这样虽然整体恢复时间延长了,但业务侧查询几乎不受影响。
另一个经验是故障演练不能省。每季度做一次节点宕机演练、一次集群重启演练、一次跨可用区切换演练。演练不仅能验证自动恢复能力,还能让运维团队熟悉故障处理流程。线上真出问题时,团队心里不慌,处置速度更快。
7.3 版本升级与变更管理
ES版本升级是自建集群最头疼的问题之一,腾讯云ES在这方面的体验要好很多。我们采用的升级策略是滚动升级,整个过程分三步:
先在测试集群完成升级验证。这一步主要跑回归测试和压测,确认新版本没有引入性能回退。
再在业务低峰期进行预发集群升级,观察一天运行指标。
最后按节点组灰度升级线上集群。以每批次10%节点为粒度,每批次升级完成观察10分钟,确认无异常后再升级下一批。
升级期间还要确保ES的replica副本数为1。如果副本数为0,升级过程中一旦节点重启,就存在数据丢失风险。这是很多团队容易忽略的细节。
变更管理上,我们所有涉及索引模板、生命周期策略、分片配置的改动都走变更评审流程,先在小规模索引组验证,再全量上线。曾经有一次我们在生产环境直接修改了索引模板导致新索引分片数翻倍,虽然没有造成数据丢失,但触发了分片分布不均匀,集群出现了严重的热点。那次事故之后,所有mapping和setting变更都强制走评审流程,非紧急变更不允许直接操作线上集群。
8. 常见问题与避坑指南
8.1 知识库检索结果不理想怎么办
很多团队遇到检索结果不理想时,第一反应是换模型或调算法,但往往忽略了数据层面的问题。根据我们的实战经验,检索效果排查顺序应该是:索引质量 -> 查询策略 -> 排序策略 -> 模型能力。
索引质量方面,要确认文档切分是否合理。我们最初把整篇文档作为一条记录写入,向量检索效果极差。后来改为按段落切分,每段控制在200到500字之间,检索精度立刻提升。段落太短会丢失上下文,太长则向量语义不聚焦,200到500字是一个经过验证的合理区间。
查询策略方面,要检查过滤条件是否正确。很多不理想结果是因为租户ID或权限过滤条件没生效,导致检索范围包含了无权限文档。我们开发了一个用于线上排障的“查询解析器”,能把最终执行到ES的DSL完整打印出来,快速定位问题出在哪个环节。
8.2 千亿级集群常见故障速查表
| 问题现象 | 核心原因 | 解决措施 |
|---|---|---|
| 查询P99延迟飙升 | 段合并或GC压力过大 | 错峰force merge,调整JVM堆参数 |
| 写入大面积reject | 写入并发过高或队列太小 | 动态限流,扩大写入线程池队列 |
| 集群状态变黄 | 分片副本数不足 | 检查故障节点,触发分片恢复或补副本 |
| 索引分片分布不均 | 新增节点没有足够分片迁移 | 使用allocate分片迁移策略,调整分片分布 |
| 缓存命中率骤降 | 缓存失效策略触发过于频繁 | 区分变更级别,高频变更单独处理 |
这张表是我们运维团队内部长期使用的问题排查手册,覆盖了大多数线上故障类型。处理故障最重要的原则是先止血再排查根因,不要在一个问题上长时间纠结而放掉整个集群的稳定性。
8.3 成本优化的几个隐藏杠杆
成本优化不是简单的缩容降配,有几个隐藏杠杆值得关注:
第一,索引副本策略动态调整。热数据保持一主一副,温冷数据可以只保留主分片,靠生命周期管理保障数据恢复能力。这能节省约30%的总存储成本。
第二,利用腾讯云ES的压缩特性。我们启用了best_compression压缩算法,虽然索引时CPU开销略有上升,但磁盘占用降低约25%,在存储成本昂贵的场景下非常划算。
第三,定期清理废弃索引。业务线经常会产生一批测试索引或临时索引,如果不定期清理,会一直占用存储资源。我们建立了索引登记制度,所有索引必须在元数据平台登记,超过TTL未续期的索引自动归档删除。
第四,避免过度分片。分片越多,集群管理开销和资源浪费越大。我们通过分片规划工具定期检查分片容量,小于10GB的分片会合并调整,维持分片数量在健康范围。
9. 一点个人总结
这个项目运行到现在,我最大的体会是:千亿级AI知识库的架构设计,最终考验的不是某一种技术的极致性能,而是整个系统的“平衡感”。ES本身确实有很多可以调优的参数,但真正决定成败的往往是那些容易被忽视的环节,比如分片规划有没有留好余量、缓存策略有没有考虑脏数据问题、数据分级有没有跟上业务增长节奏。
回到架构选型,腾讯云ES这套托管方案给团队带来的最大价值不是省了多少运维人力,而是给了我们一种“可预期性”。在千亿级数据这样复杂的系统里,可预期性比极限性能更宝贵。它让我们知道扩容会在什么时间完成、故障会在多长时间内恢复、升级会在哪个窗口执行,这些确定性支撑了业务层的稳定演进。
如果让我给正在做类似项目的团队一个建议,我会说:先把分片规划和索引生命周期设计做好,再去追求极致的查询性能调优。分片规划做错了,后面所有优化都是在有缺陷的地基上盖房子;生命周期设计好了,成本和水位控制就赢了一半。其余的事情,都可以在迭代中逐步完善,没有一蹴而就的完美架构,只有不断打磨的可靠系统。