索引拆分:大规模检索系统如何使用分布式技术加速检索?

简介: 本文介绍了分布式技术在大规模检索系统中的应用,重点探讨了如何通过索引拆分提升检索效率。常见的拆分方式有基于业务、文档(水平拆分)和关键词(垂直拆分)。其中,基于文档的拆分更易维护:新增文档仅影响一个分片,且负载更均衡,支持副本扩容应对热点查询,系统可扩展性强,是工业界主流方案。(238字)

在互联网行业中,分布式系统是一个非常重要的技术方向。我们熟悉的搜索引擎、广告引擎和推荐引擎,这些大规模的检索系统都采用了分布式技术。
分布式技术有什么优点呢?分布式技术就是将大任务分解成多个子任务,使用多台服务器共同承担任务,让整体系统的服务能力相比于单机系统得到了大幅提升。而且,在 第 8 讲 中我们就讲过,在索引构建的时候,我们可以使用分布式技术来提升索引构建的效率。
那今天,我们就来聊一聊,大规模检索系统中是如何使用分布式技术来加速检索的。.
简单的分布式结构是什么样的?
一个完备的分布式系统会有复杂的服务管理机制,包括服务注册、服务发现、负载均衡、流量控制、远程调用和冗余备份等。在这里,我们先抛开分布式系统的实现细节,回归到它的本质,也就是从「让多台服务器共同承担任务」入手,来看一个简单的分布式检索系统是怎样工作的。
首先,我们需要一台接收请求的服务器,但是该服务器并不执行具体的查询工作,它只负责任务分发,我们把它叫作 分发服务器。真正执行检索任务的是 多台索引服务器,每台索引服务器上都保存着完整的倒排索引,它们都能完成检索的工作。
当分发服务器接到请求时,它会根据负载均衡机制,将当前查询请求发给某台较为空闲的索引服务器进行查询。具体的检索工作由该台索引服务器独立完成,并返回结果。
现在,分布式检索系统的结构你已经知道了,那它的效率怎么样呢?举个例子,如果一台索引服务器一秒钟能处理 1000 条请求,那我们同时使用 10 台索引服务器,整个系统一秒钟就能处理 10000 条请求了。也就是说,这样简单的分布式系统,就能大幅提升整个检索系统的处理能力。
但是,这种简单的分布式系统有一个问题:它仅能提升检索系统整体的「吞吐量」,而不能缩短一个查询的检索时间。也就是说,如果单机处理一个查询请求的耗时是 1 秒钟,那不管我们增加了多少台机器,单次查询的检索时间依然是 1 秒钟。所以,如果我们想要缩短检索时间,这样的分布式系统是无法发挥作用的。
那么,我们能否利用多台机器,来提升单次检索的效率呢?我们先来回顾一下,在前面讨论工业级的倒排索引时我们说过,对于存储在磁盘上的大规模索引数据,我们要尽可能地将数据加载到内存中,以此来减少磁盘访问次数,从而提升检索效率。
根据这个思路,当多台服务器的总内存量远远大于单机的内存时,我们可以把倒排索引拆分开,分散加载到每台服务器的内存中。这样,我们就可以避免或者减少磁盘访问,从而提升单次检索的效率了。
即使原来的索引都能加载到内存中,索引拆分依然可以帮助我们提升单次检索的效率。这是因为,检索时间和数据规模是正相关的。当索引拆分以后,每台服务器上加载的数据都会比全量数据少,那每台服务器上的单次查询所消耗的时间也就随之减少了。
因此,索引拆分是检索加速的一个重要优化方案,至于索引应该如何拆分,以及拆分后该如何检索,工业界也有很多不同的实现方法。你可以先自己想一想,然后我们再一起来看看,工业界一般都是怎么做的。
如何进行业务拆分?
首先,在工业界中一个最直接的索引拆分思路,是根据业务进行索引拆分。那具体该如何拆分呢?
我来举个例子。在图书管理系统中,有许多不同国籍的作家的作品。如果我们将它们分成国内作品和国外作品两大类,分别建立两个倒排索引,这就完成了索引拆分。索引拆分之后,我们可以使用不同的服务器加载不同的索引。在检索的时候,我们需要先判断检索的是国内作品还是国外作品,然后在检索界面上做好选择,这样系统就可以只在一个索引上查询了。如果我们不能确认是哪类作品,那也没关系,系统可以在两个索引中并行查找,然后将结果汇总。
你会看到,基于业务的拆分是一个实用的索引拆分方案,在许多应用场景中都可以使用。但是这种方案和 业务的耦合性太强,需要根据不同的业务需求灵活调整。那我们有没有更通用的技术解决方案呢?你可以先想一下,然后我们一起来讨论。
如何基于文档进行拆分?
以搜索引擎为例,一个通用的方案是借鉴索引构建的拆分思路,将大规模文档集合随机划分为多个小规模的文档集合分别处理。这样我们就可以基于文档进行拆分,建立起多个倒排索引了。其中,每个倒排索引都是一个索引分片,它们分别由不同的索引服务器负责。每个索引分片只包含部分文档,所以它们的 posting list 都不会太长,这样单机的检索效率也就得到了提升。
但是,这样拆分出来的任意一个单独的索引分片,它检索出来的结果都不完整,我们还需要合并操作才能得到最后的检索结果。因此,对于基于文档进行拆分的分布式方案,我们的检索流程可以总结为 3 个步骤:
分发服务器接受查询请求,将请求发送给所有不同索引分片的索引服务器;
每台索引服务器根据自己加载的索引分片进行检索,将查询结果返回分发服务器;
分发服务器将所有返回的结果进行合并处理,再返回最终结果。
这种基于文档拆分的方案是随机划分的,所以我们可以不用关心业务细节。而且每个索引分片的大小都能足够相近,因此,这种拆分方式能很均匀地划分检索空间和分担检索负载。并且,如果我们将索引数据分成合适的份数,是有可能将所有数据都加载到内存中的。由于每个索引分片中的文档列表都不长,因此每台机器对于单个请求都能在更短的时间内返回,从而加速了检索效率。
但是,分片的数量也不宜过多。这是因为,一个查询请求会被复制到所有的索引分片上,如果分片过多的话,每台加载索引分片的服务器都要返回 n 个检索结果,这会带来成倍的网络传输开销。而且,分片越多,分发服务器需要合并的工作量也会越大,这会使得分发服务器成为瓶颈,造成性能下降。因此,对于索引分片数量,我们需要考虑系统的实际情况进行合理的设置。
如何基于关键词进行拆分?
在搜索引擎中,为了解决分片过多导致一次请求被复制成多次的问题,我们还可以使用另一种拆分方案,那就是基于关键词进行拆分。这种方案将词典划分成多个分片,分别加载到不同的索引服务器上。每台索引服务器上的词典都是不完整的,但是词典中关键词对应的文档列表都是完整的。
当用户查询时,如果只有一个关键词,那我们只需要查询存有这个关键词的一台索引服务器,就能得到完整的文档列表,而不需要给所有的索引服务器都发送请求;当用户同时查询两个关键词时,如果这两个关键词也同时属于一个索引分片的话,那系统依然只需要查询一台索引服务器即可。如果分别属于两个分片,那我们就需要发起两次查询,再由分发服务器进行结果合并。
也就是说,在查询词少的情况下,如果能合理分片,我们就可以大幅降低请求复制的代价了。
但是这种切分方案也带来了很多复杂的管理问题,比如,如果查询词很多并且没有被划分到同一个分片中,那么请求依然会被多次复制。再比如,以及如果有的关键词是高频词,那么对应的文档列表会非常长,检索性能也会急剧下降。此外,还有新增文档的索引修改问题,系统热点查询负载均衡的问题等。
因此,除了少数的高性能检索场景有需求以外,一般我们还是基于文档进行索引拆分。这样,系统的扩展性和可运维性都会更好。
重点回顾
我们一起来总结一下,你要掌握的重点内容。
首先,利用分布式技术,我们可以将倒排索引进行索引拆分。索引拆分的好处是:一方面是能将更多的索引数据加载到内存中,降低磁盘访问次数,使得检索效率能得到大幅度的提升;另一方面是基于文档的拆分,能将一个查询请求复制成多份,由多台索引服务器并行完成,单次检索的时间也能得到缩短。
其次,除了搜索引擎,其他大规模数据检索引擎,如广告引擎、推荐引擎等也都使用了类似的索引拆分技术。只是由于它们处理的对象不是文档,因此对于拆分方式的命名也不同。
一般来说,根据处理对象将倒排索引进行拆分,每个索引分片都可能有完整的词典,但 posting list 不完整,这种拆分方案叫作 水平拆分。如果是根据倒排索引中的关键词进行拆分,每个索引分片的词典都不完整,但是词典中的关键词对应的 posting list 是完整的,这种拆分方案叫作 垂直拆分。
总之,合理的索引拆分是分布式检索加速的重要手段,也是工业界的有效实践经验。
课堂讨论
为什么说基于文档拆分的方案会比基于关键词拆分的方案更好维护?你可以结合以下 2 个问题来考虑一下:
当有新文档加入时,会影响多少台索引服务器?
基于文档拆分:由于一个文档会划分到一个索引分片中去,只会影响这一个分片中的机器
基于关键词拆分:由于一个文档会产生很多关键词,这些关键词又存在于多个分片中的话,那么就会影响多个分片中的机器
当某些关键词是热点,会被大量查询时,每台服务器的负载是否均衡?
基于文档拆分:如上所述,可能所有分片都存在这个 关键词 的索引,所以所有分片都会被查询
基于关键词拆分:这个直接路由到 关键词所在的索引分片机器上去了
但是对于上述两种来看,第一种全部分片都会被查询,而第二种只有关键词所在分片会被查询,所有分片都被查询撑不住挂掉,另外一个撑不住只会挂掉其中一部分,怎么感觉关键词拆分会更好?
关于上述的疑问,按文档拆分,笔者的理解可能有误:一个分片负责一部分文档,这里的索引数量相对于关键词拆分来说小很多,就算查询一个关键词的时候,需要全部索引都查询,但是每一台处理的数据较少,响应速度较快,这其实就是分布式计算的方式了。
换句话说:这样一来就不存在热点服务器问题,当扛不住的时候,运维只需要无差别新增机器扩容即可(另外还可以将每一个分片 复制出几个副本专门分担这种大量查询的压力,当查询的时候,只需要均衡分配到副本上查询处理即可)

相关文章
|
4月前
|
存储 缓存 NoSQL
存储系统:从检索技术角度剖析 LevelDB 的架构设计思想
LevelDB是Google开源的高性能键值存储系统,基于LSM树优化,采用跳表、读写分离、SSTable分层与Compaction等技术,结合BloomFilter、缓存机制与索引分离设计,显著提升数据读写与检索效率,广泛应用于工业级系统中。(238字)
|
4月前
|
存储 机器学习/深度学习 算法
最近邻检索(下):如何用乘积量化实现「拍照识花」功能?
AI时代,以图搜图、拍图识物广泛应用。其核心是图片特征提取与高维向量相似检索。本文解析聚类算法(如K-Means)与局部敏感哈希的区别,详解乘积量化压缩向量、倒排索引加速检索的技术原理,揭示图像检索背后的高效机制。(238字)
|
4月前
|
机器学习/深度学习 数据采集 自然语言处理
搜索引擎:输入搜索词以后,搜索引擎是怎么工作的?
搜索引擎通过爬虫抓取网页,经索引系统处理生成倒排索引,再由检索系统结合分词、纠错、推荐等技术理解用户意图,利用位置信息和最小窗口排序,精准返回结果。其核心在于以查询词为约束,实现高效相关性匹配。
|
4月前
|
机器学习/深度学习 搜索推荐 算法
广告系统:广告引擎如何做到在 0.1s 内返回广告信息?
广告系统是互联网核心营收支柱,支撑Google、Facebook等公司超80%收入。其本质是高并发、低延迟的实时检索系统,需在0.1秒内完成百万级广告匹配。本文详解广告引擎架构:通过标签过滤、树形分片优化索引;引入向量检索实现智能匹配;采用非精准打分预筛+深度学习精排的混合排序策略;并在离线索引构建时前置过滤无效广告,压缩检索空间。结合业务特点,从索引、召回到排序全方位提升性能,保障高效精准投放。
|
4月前
|
机器学习/深度学习 算法 搜索推荐
精准 Top K 检索:搜索结果是怎么进行打分排序的?
搜索引擎排序直接影响用户体验,核心是Top K检索。本文介绍三种打分算法:经典TF-IDF衡量词项权重;BM25在此基础上优化,引入文档长度、词频饱和等因子;机器学习则融合数百特征自动学习权重,提升排序精度。最后通过堆排序高效实现Top K结果返回,兼顾性能与效果。(239字)
|
4月前
|
存储 NoSQL 定位技术
空间检索(上):如何用 Geohash 实现「查找附近的人」功能?
本文介绍了如何高效实现“查找附近的人”功能,提出基于Geohash的区域编码与索引方案。通过将二维空间划分为带层次的编码区域,利用一维索引(如跳表、哈希表)快速检索目标区域及邻接区域用户,结合非精准与精准Top K检索策略,在保证性能的同时控制误差。适用于社交、出行等LBS场景。
|
4月前
|
机器学习/深度学习 搜索推荐 算法
非精准 Top K 检索:如何给检索结果的排序过程装上加速器?
本文介绍了非精准 Top K 检索的优化思路及三种实现方法:基于静态质量得分排序截断、胜者表利用词频打分、分层索引两阶段检索。核心思想是将计算前置至离线阶段,降低在线打分开销,通过快速截断提升检索效率。该方法广泛应用于搜索与推荐系统,结合精准排序形成高效两级检索架构。
|
3月前
|
人工智能 弹性计算 对象存储
玄晶引擎:基于阿里云生态的全流程AI自动化方案,赋能中小微企业低成本数字化转型
玄晶引擎是阿里云生态原生AI自动化平台,专为中小微企业设计。依托通义千问、ACK、OSS、VectorDB等服务,实现“内容生产—流量分发—精准获客—成交转化”全流程闭环。云原生架构+零代码操作,算力成本降60%,人力节省超60%,3个月可回本。
280 15
|
4月前
|
存储 搜索推荐 定位技术
空间检索(下):「查找最近的加油站」和「查找附近的人」有何不同?
本文探讨了动态范围内“查找最近的k个目标”问题,如导航中找最近加油站。针对查询范围不固定场景,传统GeoHash多层查询效率低、存储冗余。为此,提出四叉树方案:通过树形结构递归扩大检索范围,避免重复查找;采用非满四叉树动态分裂节点,提升空间利用率;并可结合前缀树对GeoHash字符串索引,高效支持范围扩展查询。最后引出高维场景下的k-d树等通用结构,为近邻检索提供更广泛解决方案。(239字)
|
5月前
|
存储 缓存 弹性计算
阿里云服务器实例怎么选?经济型、通用算力型、计算型、通用型、内存型区别及选择参考
在我们通过阿里云的活动选购云服务器的时候会发现,可选的云服务器实例主要以经济型、通用算力型、计算型、通用型、内存型为主,相同实例可能又分为多个实例规格(例如通用算力型u1与u2i),另外,同配置的云服务器往往有多个不同的实例可选。本文为大家详细介绍阿里云的经济型、通用算力型、计算型、通用型和内存型实例的性能特点及适用场景,以供大家选择参考。
572 25