2026年7月2日 周四晚上19:30,报名腾讯会议了解“如何构建自进化的动态知识库(Brain)”(限30人)
免费POC, 零成本试错
FDE知识库

FDE知识库

学习大模型的前沿技术与行业落地应用


收藏

得物自研DSearch3.0搜索核心引擎升级之路

发布日期:2025-05-12 19:53:01 浏览次数: 2183
作者:得物技术

微信搜一搜,关注“得物技术”

推荐语

得物自研DSearch3.0引擎升级,性能与效率的双重飞跃。

核心内容:
1. 交易和社区搜索业务增长带来的性能瓶颈和运维挑战
2. DSearch1.0至3.0的索引结构演进与优化
3. 性能和效果提升的具体表现及技术细节解析

杨芳贤
53AI创始人/腾讯云(TVP)最具价值专家

目录

一、背景

二、引擎开发技术方案

    1. DSearch1.0索引层整体结构

    2. DSearch2.0的索引升级

    3. DSearch3.0搜索核心升级

三、性能和效果提升

四、总结

背景

随着交易和社区搜索业务稳步快跑,基建侧引擎越来越复杂,之前搜索底层索引查询结构已经存在较为严重的性能瓶颈。成本和运维难度越来越高。在开发效率上和引擎的稳定性上,也暴露出了很多需要解决的运维稳定性和开发效率短板。而在引擎的业务层部分也需要逐步升级,来解决当前引擎中召回层和业务层中各个模块强耦合,难维护,迭代效率低下等问题。

引擎开发技术方案

DSearch1.0索引层整体结构

DSearch1.0的索引结构比较特殊一些,总体上使用了全局rcu的设计思想,整体架构上单写多读,所以实现了并发高性能无锁读,内部数据结构都是无锁数据结构,所以查询性能高。在写操作上因为rcu机制实现写入无锁。整体上优点读性能高,没有传统段合并操作带来的磁盘抖动。缺点是索引地址和操作系统强相关,运维复杂,热更新受限。全局地址分配难以并行写入,构建瓶颈明显。无法对浪费的内存进行回收导致内存空间利用率低,索引空间占用大。总体结构如图所示:

DSearch2.0的索引升级

DSearch2.0分段索引整体设计

引擎2.0索引升级采用经典段合并架构,除了继承了段合并中优异的高性能写入性能和查询已经索引合并等优势外,针对段合并中频繁的正排字段更新等带来的高IO缺点。我们设计了新的正排字段原地更新索引,使新的DSearch2.0引擎拥有Redis的高性能写入和查询,也拥有lucene的紧凑索引和索引合并带来的内存空间节省的优势。

※ 索引段结构

  1. 每个索引段包含了文档文件,用于紧凑存放document中的各个字段的详细信息。字符串池文件是对document中所有的字符串进行统一顺序存储,同时对字符串进行ID化,每个字符串ID就是对应于字符串池中的offset偏移

  2. 可变数组文件是专门存放数组类型的数据,紧凑型连续存放,当字段更新的时候采用文件追加append进行写。最终内存回收通过段之间的compaction进行。FST索引文件是专门存放document中全部字符串索引。每个fst的node节点存放了该字符串在字符串池中的偏移offset。而通过字符串的offset,能够快速在倒排termoffset数组上二分查找定位到term的倒排链。

  3. 倒排文件是专门存放倒排docid,词频信息、位置信息等倒排信息,其中docid倒排链数据结构会根据生成段的时候计算docid和总doc数的密度来做具体判断,如果密度高于一定阈值就会使用bitmap数据结构,如果小于一定阈值会使用array的数据结构

  4. 标记删除delete链主要是用于记录段中被删除的document,删除操作是软删除,在最后查询逻辑操作的时候进行最后的过滤。

  5. 实时增量的trie树结构,实时增量段中的前缀检索和静态段中的前缀检索数据结构不一样,trie因为能够进行实时更新所以在内存中使用trie树。

  6. 段中的metadata文件,metadata文件是记录每个段中的核心数据的地方,主要记录段内doc数量,段内delete文档比例,实时段的metadata会记录kafka的offset等核心数据。

Document文档和索引结构

※ Document文档数据结构

  1. Document文档使用紧凑型存储,其中array和字符串类型单独存放,其他字段连续存放,string和array字段存放。

  2. array字段类型数据直接存放在可变数组文件区,连续追加写。

  3. string字符串池对所有字符串进行连续存放,多个doc中同一个字符串引用同一个字符串地址,节省大量字符串存放空间。

※ 倒排索引文件结构

  1. 倒排索引文件存放docid倒排和Tf以及位置position数据。其中内存实时段中的倒排索引数据结构是固定一种类型array类型。而内存实时段固化为静态段的时候,倒排数据结构会根据docid中的密度进行选择array和bitmap存储。当docid密度大于一定阈值是bitmap,反之是array结构。

  2. Tf数据结构是一个uint16的数组,数组长度和docid的数组长度一致,所以当确定了某个docid时候,也随即确定了它的tf信息。

  3. postion信息存储是一个二维数组的格式,第一层数组存放的是对应于term的在字符串池的offset,因为term在字符串池中已经ID化,所以offset可以表示唯一term。第二层数组是该term在字段中多次出现的位置,使用uint16存储。

※ 前缀检索文件

  1. FST静态段文件

    a. 静态段中前缀是fst的数据结构,因为fst一旦建立是不能够进行修改的,所以在段合并的时候需要对所有term进行排序然后再构建fst结构。

    b. fst的node节点存放了对应于term的字符串池的offset。当需要查询一个term的倒排结构时候,需要先查询该term的字符串池的offset,然后拿该offset去倒排的termoffset文件中二分查找找到对应的倒排positionlist结构拿到对应倒排。所以一次term到倒排的查询需要查询一次fst+一次二分查询。

    c. term到倒排的查询一次fst+一次二分查找效率不高,所以针对term到倒排查询,新增了第二种HashMap索引,直接通过term到倒排的offset索引,这个选项在建表的时候可以配置。

  2. 实时段RcuTrie树索引

    a. 实时段中需要支持边写边读,前缀检索需要支持并发读写。引擎中trie树是rcu实现,单线程更新,多线程并发读,trie树写更新节点内存延迟回收。

倒排索引和查询树逻辑

※ 倒排链优化

  1. DSearch1.0的roaringbimap倒排索引在低密度数据量上存在一些瓶颈,比如对于倒排链比较短的情况下,roaringbitmap的container大部分都是array结构,在倒排链查询和合并都会进行一次二分查找,在大面积的倒排链合并中是个相当大的性能瓶颈。

  2. 针对上面所说的情况对roaringbitmap进行了精简,只存array或者bitmap合并的时候不需要查找,直接链式合并。

※ 逻辑树合并优化

  1. DSearch2.0重点从逻辑语法树和倒排入手,优化语法树,减少合并树高,从二叉树合并变成单层合并。

  2. 优化倒排链合并方式,采用原地倒排链合并,消除倒排合并临时对象,同时引入多线程并行合并,减少长尾提高性能。

增量更新逻辑

※ 增量实时写入逻辑

  1. 引擎支持多个并发实时段,这个由配置文件通过配置来进行配置。多个实时段能够提升并发写入的性能。

  2. 每个实时段对应一个写入队列,提高并发写入吞吐。

  3. 每个段真实写入一条信息会同步原子更新消费的kafka的offset,用于对后面进程重启等恢复数据做准备。

  4. 当进程重启或者异常退出时候,会读取metadata文件中的最后一条kafka offset进行重新消费增量在内存中重新构建新的正排、文档和倒排等信息,完成数据的恢复。

实时段固化和段合并策略

※ 实时段固化逻辑:

  1. 当实时段内随着增量写,doc文件大小超过128M时候会进行内存实时段固化操作。

  2. 固化操作开始时,会先生成新的内存实时段,老的内存实时段会变成只读内存段。

  3. 遍历按整个只读内存段,构建新的索引和新的正排结构生成新的静态段。

※ 段合并策略:

  1. 实时段固化的小静态段因为大小比较小,会优先和之前固化后的小段进行合并,按照1,2,4,8进行合并,逐步合并成静态段最大的上限。

  2. 静态段的合并触发策略是当静态段中delete的doc比例超过了30%会触发静态段之间的合并,合并会按照近邻合并原则,从左右近邻中选取一个最小doc数的段进行合并,进而新生成一个新的段。

查询和更新中的并发控制

※ 查询流程

引擎查询时候,先遍历查询实时段,然后再查询静态段。实时段查询存在最大增量查询截断,当实时段查询到最大增量截断时实时段停止查询。


实时段查询后,查询静态段。静态段中包含了全量构建索引的全量最大offset记录同时全量的doc是通过质量分进行排序,所以在全量段查询的时候,先遍历质量分最大的全量段,逐步往后面静态段查询,直到查询到全量截断。


实时段查询和静态段查询结果进行merge作为最终的查询结果。

※ 更新并发控制

因为DSearch2.0的索引更新是直接在实时段或者静态段进行更新,所以存在多线程读写问题。尤其是正排字段更新写入量大更新频繁。同时更新涉及到所有的实时段和静态段,较为复杂。


为了解决正排字段和倒排的更新问题,新版本引擎引入了document文档锁池,对每个doc进行hash计算落到锁池中具体一个锁上来减少锁冲突,当前锁池内有多个个文档锁。文档锁在文档进行拷贝和更新的时候会进行锁住。

DSearch3.0搜索核心升级

异步非阻塞图调度框架

※ 引擎主要改造:

  1. 图框架支持RPC异步非阻塞请求:引擎图框架RpcServer服务使用brpc的异步处理无需同步阻塞等待调度完成,只需框架调度完算子返回结果,不阻塞RpcServer线程,例如:当前引擎调用neuron服务是同步调用,当neuron服务负载高阻塞时,同步调用会导致拖住引擎RpcServer处理线程,新的异步非阻塞模式引擎client在调用引擎后已经返回,等待引擎RpcServer中异步调度框架中remote异步算子回调,减少外部服务影响引擎。

  2. 减少线程切换:图框架调度器会优先调度当前运行线程,同时使用M:N类型的bthread线程池,线程切换会更小,执行效率高。

  3. RPC服务和框架算子独立:引擎RPC服务和框架算子完全解耦,跨集群部署算子服务无需任何改造,实现算子脱离运行环境。

  4. 高效的算子异常处理和超时机制:每个算子维护自己的运行超时时间和请求到算子调度执行的超时时间,对整个请求流程中各算子执行更加精准。 

  5. 动态图支持:图框架支持静态图和动态图业务组合式调用。支持静态子图和动态子图调用等复杂业务组合。

  6. 复杂子图支持:图框架支持嵌套子图,支持自调用模型,可以实现复杂单节点多功能调用。

算子间数据交换Table设计

※ 引擎主要改造:

  1. 列式数据共享优化:算子交换数据全部存放在Table列中,Table中全部共享列式数据,省去大面积数据拷贝,大幅提升引擎业务执行性能。

  2. 兼容引擎索引中doc数据:引擎索引中doc行式存储有很多优点,比如多字段访问效率高等,Table设计中考虑了行式存储优点,不仅存高频的列字段也储存了引擎内部的doc*以及对应FieldDef*,能直接方便访问索引数据,接口统一,易于迭代。

  3. 打通FlatBuffer序列化协议:当前引擎FlatBuffer序列化传输协议和引擎内部数据出口需要多次遍历转换,需要拷贝很多数据,新Table的设计内部数据列和FlatBuffer内部的数据列互转互通,节省大量内部拷贝同时避免了字段兼容等问题。

  4. 支持原地排序和标记删除:Table数据表,支持原地sort操作和标记删除操作,节省数据排序时大量数据的拷贝和删除操作中导致的数据重排等拷贝操作,提升性能。

算子间数据交换Table设计

※ 引擎主要改造:

  1.  动态图支持:DSsearch3.0支持动态图编排,主要通过业务方通过动态编排请求来组织对应的算子编排逻辑,实现业务方自主编排调度逻辑,方便整体业务开发。

  2. Remote远程调用支持:通过开发远程异步调用算子,支持DSearch3.0跨集群调用,实现多机算子化互联互通。提高引擎的整体纵向拓展能力。

  3. 引擎算子库复用:通过设计统一的算子接口,开发基础的可复用框架算子,支持配置化组合运行图,实现业务逻辑快速复用和开发,提高整体引擎开发效率。

性能和效果提升

DSearch在2024年Q1季度索引升级开发完成后逐步推全到交易和社区等各个主场景业务中,最后拿到了很多超预期结果:

索引内存优化超出预期:社区搜索和交易搜索总索引单分片优化60%。

构建和写入性能优化超出预期:社区搜索和交易搜索主表写入性能提升10倍。

索引更新优化超预期:社区和交易主表更新时间提升接近10倍。

性能优化符合预期:社区搜索平均rt降低一倍,P99晚高峰降低2倍。

总结

DSearch引擎从开始的DSearch1.0的搜索引擎逐步经历了DSearch2.0的分段式索引改造升级,又经历了DSearch3.0的全图化引擎升级。逐步将DSearch引擎升级到业界较为领先的支持内存型、磁盘型多段式搜索引擎,为支持得物业务的发展做出了重要的贡献,后续DSearch会围绕着通用化、自迭代、高性能等多个方向继续升级,将DSearch引擎迭代到业界领先的引擎。

53AI,企业落地大模型首选服务商

产品:场景落地咨询+大模型应用平台+行业解决方案

承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

添加专属顾问

回到顶部

加载中...

扫码咨询

扫码登录
登录即表示您同意《53AI网站服务协议》
服务协议

欢迎您使用【53AI 官方网站】(以下简称“本网站”或“我们”)。本《会员服务协议》(以下简称“本协议”)是您(以下简称“会员”或“用户”)与【深圳市博思协创网络科技有限公司】之间关于注册、登录及使用本网站会员服务所订立的法律协议。

在您注册或登录前,请务必审慎阅读、充分理解各条款内容,特别是免除或限制责任的条款、知识产权条款、争议解决条款等。此类条款将以加粗形式提示您注意。 当您通过微信公众号授权、手机验证码验证或其他方式成功登录本网站时,即视为您已完全理解并同意接受本协议的全部内容。

一、 定义

本网站:指由【深圳市博思协创网络科技有限公司】运营的,域名为【53ai.com】的网站及相关移动端页面。

会员服务:指本网站向注册会员提供的知识库文章查阅、内容检索及其他相关增值服务。

知识库内容:指本网站发布的包括但不限于文字、图表、数据、研究报告、行业分析等数字化内容资源。

二、 账号注册与登录

登录方式:本网站支持以下登录方式,您可根据实际情况选择:

微信公众号授权登录:您同意将您的微信OpenID信息授权给本网站,用于创建或关联会员账号。

手机验证码登录:您需提供真实有效的手机号码,并通过短信验证码完成身份验证与登录/注册。

账号安全:您的账号仅限您本人使用,禁止赠与、借用、租用、转让或售卖。因您保管不善导致的账号被盗、密码泄露等损失,由您自行承担。

实名认证:根据相关法律法规要求,我们可能要求您在特定功能下完成实名认证。如您拒绝提供,可能无法使用部分或全部服务。

未成年人保护:若您未满18周岁,请在法定监护人的陪同下阅读本协议,并在征得监护人同意后使用本服务。

三、 服务内容与规范

知识库查阅权限:会员登录后,有权按照其会员等级对应的权限范围,在线浏览、检索本网站知识库中的相关文章及内容。

服务变更:我们有权根据业务发展需要,调整、变更或终止部分服务内容,并将以网站公告、公众号消息等方式提前通知。

禁止行为:您在使用服务时不得实施以下行为:

利用技术手段批量爬取、下载、转存知识库内容;

将知识库内容用于商业目的或未经授权地向第三方传播;

干扰本网站正常运行或侵犯其他用户合法权益;

发布违法违规信息或从事违反公序良俗的活动。

四、 知识产权声明

权利归属:本网站知识库中的排版设计、软件代码等内容的知识产权均归【公司全称】或原权利人所有,受《中华人民共和国著作权法》等法律保护。

有限许可:本网站授予会员一项非独占、不可转让、不可转授权的普通许可,仅限于个人学习、研究之目的在线查阅知识库内容。

侵权追责:未经书面许可,任何单位或个人不得以任何形式复制、转载、摘编、镜像、汇编或以其他方式使用上述内容。一经发现,我们保留追究其法律责任的权利。

五、 个人信息保护

我们重视对您个人信息的保护。关于我们如何收集、使用、存储和保护您的个人信息,请单独阅读 《隐私政策》。

您通过微信公众号授权或手机号验证所提供的信息,我们将严格按照《个人信息保护法》的规定处理,仅用于身份识别、服务提供及安全验证等必要用途。

您可以随时通过网站设置或联系客服行使查阅、更正、删除个人信息及撤回授权同意的权利。

六、 免责声明

内容准确性:知识库内容仅供参考,不构成专业建议。我们不对其完整性、准确性、时效性作任何明示或暗示的保证,您应自行判断并承担使用风险。

不可抗力:因自然灾害、政策法规变化、网络故障、第三方平台接口异常(如微信接口维护、运营商短信通道故障)等不可抗力导致的服务中断或延迟,我们不承担违约责任。

第三方链接:本网站可能包含指向第三方网站的链接,该等网站的内容和服务不受我们控制,请您自行甄别风险。

七、 违约责任

如您违反本协议约定,我们有权视情节采取警告、限制功能、暂停服务、注销账号等措施,并保留要求赔偿损失的权利。

如因您的违约行为导致我们遭受行政处罚、第三方索赔或商誉损失,您应承担全部赔偿责任(包括但不限于罚款、赔偿金、律师费、公证费等)。

八、 法律适用与争议解决

本协议的订立、执行和解释均适用中华人民共和国大陆地区法律。

因本协议产生的或与本协议有关的任何争议,双方应友好协商解决;协商不成的,任何一方均可向【公司所在地】有管辖权的人民法院提起诉讼。

九、 其他

本协议构成双方就本服务达成的完整协议,取代此前任何口头或书面约定。

本协议任一条款被认定为无效或不可执行的,不影响其他条款的效力。

我们对本协议享有最终解释权,并在法律允许的范围内保留随时修改的权利。修改后的协议一经公布即生效,继续使用服务即视为同意修订内容。


已查阅