您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

百万并发场景中倒排索引与位图计算的实践

时间:2023-01-09 14:12:49  来源:  作者:开源中国

来源 | OSCHINA 社区

作者 | 京东云开发者-京东物流 朗元辉

原文链接:https://my.oschina.NET/jiagoushi/blog/5549507

背景

Promise 时效控单系统作为时效域的控制系统,在用户下单前、下单后等多个节点均提供服务,是用户下单黄金链路上的重要节点;控单系统主要逻辑是针对用户请求从规则库中找出符合条件的最优规则,并将该规则的时效控制结果返回客户端,比如因为临时疫情等原因针对仓、配、商家、客户四级地址等不同维度进行精细粒度的时效控制。

该系统也是 Promise 侧并发量最大的系统,双 11 高峰集群流量 TPS 在百万级别,对系统的性能要求非常高,SLA 要求在 5ms 以内,因此对海量请求在规则库 (几十万) 中如何快速正确匹配规则是该系统的技术挑战点。

朴素的解决方案

按照朴素的思想,在工程建设上,通过异步方式将规则库逐行缓存到 redis,Key 为规则条件,Value 为规则对应结果;当用户请求过来时,对请求 Request (a,b,c,d..) 中的参数做全组合,根据全组合出的 Key 尝试找出所有可能命中的规则,再从中筛选出最优的规则。如下图所示

该方案面临的问题是全组合的时间复杂度是 2**n,n≈12;算法的时间复杂度高且算法稳定性差,最差情况一次请求需要 4096 次计算和读取操作。当然在工程上我们可以使用本地缓存做一些优化,但是无法解决最根本的性能问题。架构简图如下所示:

新的解决方案

上面方案是从行的角度看待匹配定位的,能够命中的行的每一列必然也是符合条件的,这里面存在某种隐约的内在联系。能否反过来思考这个问题,为此我们尝试进行新的方案,当然架构简图依然如上图所示,核心优化的是命中算法。

新的方案整体采 用列的倒排索引和倒排索引位运算的方式,使得计算复杂度由原来的 2n 降至 n**,且算法稳定性有非常好的保证。其中列的倒排索引是对每列的值和所分布的行 ID (即 Posting List) 建立 KV 关系,倒排索引位运算是对符合条件的列倒排索引进行列间的位运算,即通过联合查询以便快速找到符合条件的规则行。

算法详细设计1. 预计算生成列的倒排索引和位图

通过对每列的值进行分组合并生成 Posting List,建立列值和 Posting List 的 KV 关系。以下图为例,列 A 可生成的倒排索引为:301={1},201={2,3,4,5} 等,需要说明的一点,空值也是一种候选项,也需要生成 KV 关系,如 nil={7}。

2. 生成列的倒排索引对应位图

将步骤 1 的倒排索引转成成位图,方便后续的位图计算,转换规则为行 ID 对应位图的下标位(步骤 1、2 可以合并操作)。

3. 根据用户请求查找列位图,通过位图计算生成候选规则集

将用户请求中的入参作为 Key,查找符合条件的位图,对每一列进行列内和空值做 || 运算,最后列间位图做 & 运算,得到的结果是候选规则集,如下图所示:

4. 从候选规则库中,根据业务优先级排序,查找最优的规则

以候选规则为基点,按照业务优先级排序,进行逐级位运算 &,当遍历完或位运算为 0 时,找到最后不为空的即为最优规则,该过程是从候选规则库逐渐缩小最优范围的过程。需要说明某列当用户请求位图不存在时,需要使用对应的空位图进行参与,以 B 列为例,入参 B_1102 不存在,需要使用 B_nil 参与 &。

复杂度分析

通过上面的例子我们可以看到,在时间复杂度方面查找候选规则集时,进行一轮 || 运算,一轮 & 运算;在查找最优规则时进行一轮 & 运算,所以整体复杂度是 3n≈n。

在空间复杂度方面,相比原来的行式存储,倒排索引的存储方式,每列都需要存储行 ID,相当于多了 *(n-1)Posting List 存储空间,当然这是粗略计算,因为实际上行 ID 的存储最终转换为位图存储,在空间上有非常大的压缩空间。

工程问题 - 压缩位图

如果倒排索引位图非常稀疏,系统会存在非常大的空间浪费。我们举一个极端 case,若千万规则库中命中的行 ID 是第 1000 万位,按照传统方式 BitSet 进行存储,需要消耗 1.2MB 空间,在内存中占用存在严重浪费,有没有压缩优化方案,在 RoaringBitMap 压缩位图方案中我们找到,相同场景在压缩位图方式下仅占 144bytes;即使在 1000 万的位图空间,我们随机存储 1 万个值,两者比也是在 31K vs 2MB,近 100 倍的差距,总的来说 RoaringBitMap 压缩率非常大。

RoaringBitMap 本质上是将大块的 bitmap 拆分成各个小块,其中每个小块在需要存储数据的时候才会存在,所以当进行交集或并集运算的时候,RoaringBitMap 只需要去计算存在的块而不需要像 bitmap 那样对整个大块进行计算,既做到了压缩的存储又做到计算性能的提升。

以下图 821697800 为例,对应的 16 进制数为 30FA1D08, 其中高 16 位为 30FA,低 16 位为 1D08。先用二分查找从一级索引(即 Container Array)中找到数值为 30FA 的容器,该容器是一个 Bitmap 容器,然后在该容器查找低 16 位的数值 1D08,即十进制下 7432,在 Bitmap 中找到相应的位置,将其置为 1 即可。

适用场景分析

回顾上面的设计方案我们可以看到,这种方式仅适用于 PostingList 简单如行 ID 的形式,如果是复杂对象就不适合用位图来存储。另外仅适用于等值查询,不适用于 like、in 的范围查询,为什么有这种局限性?因为这种方式依赖于搜索条件的空间,在方案中我们将值的条件作为搜索的 Key,值的条件空间希望尽可能是一个有限的、方便穷举的、小的空间。而范围查询导致这个空间变成难以穷举、近乎无限扩张的、所以不适用。

其他优化方式

除了使用位运算的方式对倒排索引加速,考虑到 Posting List 的有序性,还有其他的方式比如使用跳表、Hash 表等方式,以 ES 中采用的跳表为例,进行 & 运算实际就是在查找两个有序 Posting List 公共部分,以相互二分查找的形式,将时间复杂度控制在 log (n) 的级别。

具体参见《工业界如何利用跳表、哈希表、位图进行倒排索引加速?》:https://time.geekbang.org/column/article/221292?utm_source=related_read&utm_medium=article&utm_term=related_read



Tags:索引   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,如有任何标注错误或版权侵犯请与我们联系(Email:2595517585@qq.com),我们将及时更正、删除,谢谢。
▌相关推荐
来源 | OSCHINA 社区作者 | 京东云开发者-京东物流 朗元辉原文链接:https://my.oschina.net/jiagoushi/blog/5549507背景Promise 时效控单系统作为时效域的控制系统,在用户下...【详细内容】
2023-01-09  Tags: 索引  点击:(0)  评论:(0)  加入收藏
新智元报道编辑:编辑部【新智元导读】ChatGPT的横空出世,让Pichai真的怕了。没有大力发展聊天机器人,是谷歌的战略性失误吗?这个月,OpenAI的ChatGPT横空出世,立刻在AI圈掀起一股大...【详细内容】
2022-12-23  Tags: 索引  点击:(98)  评论:(0)  加入收藏
概述人类存储信息的发展历程大致经历如下: 由于是个人凭着自己理解总结的,因此可能不一定精确,但是毋庸置疑的是,在当代,各大公司机构部门的数据都是维护在数据库当中的。数据库...【详细内容】
2022-12-09  Tags: 索引  点击:(2)  评论:(0)  加入收藏
最近,美国人工智能研究机构Openai发布了最新的大语言模型ChatGPT,惊艳的性能在海外掀起了测试的热潮。通过对各种领域专业知识的训练,ChatGPT不仅可以帮助人们搜索知识,还能进行...【详细内容】
2022-12-06  Tags: 索引  点击:(32)  评论:(0)  加入收藏
萧箫 发自 凹非寺量子位 | 公众号 QbitAI总是搜不到想要的资料?试试直接给AI描述你要查的内容!这可不是什么“智能推荐”功能,而是一个新出炉的AI搜索引擎 Metaphor。与谷歌百...【详细内容】
2022-11-15  Tags: 索引  点击:(200)  评论:(0)  加入收藏
谈到索引失效,大家可能都能列举出几个场景,比如:后模糊查询、条件中带函数、索引中断等等。今天我想和你分享另一个场景:索引成本分析。我先用一个具体的例子来描述一下这个场景...【详细内容】
2022-11-07  Tags: 索引  点击:(51)  评论:(0)  加入收藏
背景由于公司项目需要用到全文搜索这个功能,而且要求轻量级,不能用复杂的ES,于是在网上搜索资料。一次偶然机会,发现了一个名字特别显眼的搜索引擎——MeiliSearch!Mei...【详细内容】
2022-11-03  Tags: 索引  点击:(137)  评论:(0)  加入收藏
众所周知,高质量的内容一直受到搜索引擎的喜爱,随着搜索引擎对高质量内容网站的喜爱,越来越多的站长开始效仿。搜索引擎对质量网站的判断标准在不同阶段不同,搜索引擎如何判断网...【详细内容】
2022-11-01  Tags: 索引  点击:(59)  评论:(0)  加入收藏
0 HBase简介HBase是一个构建在HDFS之上,用于海量数据存储分布式列存储系统。 表的每行都是按照RowKey的字典序排序存储 表的数据是按照RowKey区间进行分割存储成多个region所...【详细内容】
2022-10-15  Tags: 索引  点击:(48)  评论:(0)  加入收藏
网站要想成功,必须引入流量。从站外引入的流量来源可以分为三种:搜索引擎、外部链接和直接访问,网站分析中的流量引入分析即是分析这些来源流量的数量和质量。搜索引擎一般是网...【详细内容】
2022-10-12  Tags: 索引  点击:(87)  评论:(0)  加入收藏
▌简易百科推荐
介绍本文主要介绍一种通过windbg分析内存泄漏的方法,方法也适用linux。这个内存泄漏问题比较经典,我个人认为是自己这么多年bug定位中一个非常好的bug,并且在分析的过程中,也有...【详细内容】
2023-01-09  睡在床板下    Tags:内存泄漏   点击:(8)  评论:(0)  加入收藏
来源 | OSCHINA 社区作者 | 京东云开发者-京东物流 朗元辉原文链接:https://my.oschina.net/jiagoushi/blog/5549507背景Promise 时效控单系统作为时效域的控制系统,在用户下...【详细内容】
2023-01-09  开源中国     Tags:索引   点击:(0)  评论:(0)  加入收藏
让我们深入探讨 DevOps 和 DevSecOps 管道中密码密钥管理的各个方面。 当今的数字业务有望以闪电般的速度创新、执行和发布产品。自动化工具的广泛采用,加上 DevOps 和DevSec...【详细内容】
2023-01-09  qaseven     Tags:软件开发   点击:(3)  评论:(0)  加入收藏
nvtracker允许deepstream pipeline使用底层跟踪器库来跟踪检测到的具有持久(可能唯一) ID 的对象。nvtracker支持任何实现 了NVNvDsTracker API 的底层库,其自带的NvMultiObjec...【详细内容】
2023-01-08  程序员修行  今日头条  Tags:deepstream   点击:(5)  评论:(0)  加入收藏
WebAssembly (WASM) 在过去几年一直是一个流行词。 这是一项引起广泛关注但在实践中应用较少的技术。 我一直很好奇它的现状,所以我调查并总结了我的发现。 其中一些可能会让...【详细内容】
2023-01-07  启辰8  今日头条  Tags: WebAssembly   点击:(4)  评论:(0)  加入收藏
前言项目是基于swoole开发,框架也是公司内自己开发的框架,并没有用外界热门的swoole框架,swoole是4.0.0版本。项目需要执行大量的自动任务,框架是通过swoole的sendMessage方法将...【详细内容】
2022-12-29  博读代码  51CTO  Tags:后端   点击:(12)  评论:(0)  加入收藏
现在的各种开源项目中使用 Vue 的越来越多了,作为一个后端程序员不会点 Vue 也都玩不转了。所以抽空学习了一下 Vue 的简单用法,整理成笔记,方便有需要的同学一起学习。Vue 是...【详细内容】
2022-12-28  猿来猿往  今日头条  Tags:VUE   点击:(16)  评论:(0)  加入收藏
C语言几乎唯一的缺点就是,需要手动管理内存。抛开这点之外,我觉得其他语言都不如C语言[呲牙]所以,虽然自动内存管理比较复杂,但我还是给scf编译器框架加了静态的GC算法。在编程...【详细内容】
2022-12-27  底层技术栈  今日头条  Tags:编译器   点击:(14)  评论:(0)  加入收藏
编译器在经过词法分析、语法分析之后,就把源代码变成了抽象语法树(AST)。接下来,编译器的任务就是把AST变成机器码。AST,是一个表示代码逻辑的树形结构,它是不能直接顺序遍历的,而...【详细内容】
2022-12-26  底层技术栈  今日头条  Tags:编译   点击:(13)  评论:(0)  加入收藏
大家在平时的开发过程中估计不会经常碰到需要主动取消一个 Fetch 请求的需求,所以一部分同学可能对这一块知识不是很了解。没有关系,看完这篇文章你就能够掌握关于如何终止一...【详细内容】
2022-12-25  嘻呱互联   网易号  Tags: Promise   点击:(12)  评论:(0)  加入收藏
站内最新
站内热门
站内头条