0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

OSC开源社区 来源:OSCHINA 社区 2023-01-10 10:35 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

背景

Promise 时效控单系统作为时效域的控制系统,在用户下单前、下单后等多个节点均提供服务,是用户下单黄金链路上的重要节点;控单系统主要逻辑是针对用户请求从规则库中找出符合条件的最优规则,并将该规则的时效控制结果返回客户端,比如因为临时疫情等原因针对仓、配、商家、客户四级地址等不同维度进行精细粒度的时效控制。 该系统也是 Promise 侧并发量最大的系统,双 11 高峰集群流量 TPS 在百万级别,对系统的性能要求非常高,SLA 要求在 5ms 以内,因此对海量请求在规则库 (几十万) 中如何快速正确匹配规则是该系统的技术挑战点。

朴素的解决方案

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

3872ffc4-902a-11ed-bfe3-dac502259ad0.png

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

389ae19c-902a-11ed-bfe3-dac502259ad0.png

新的解决方案

上面方案是从行的角度看待匹配定位的,能够命中的行的每一列必然也是符合条件的,这里面存在某种隐约的内在联系。能否反过来思考这个问题,为此我们尝试进行新的方案,当然架构简图依然如上图所示,核心优化的是命中算法。 新的方案整体采用列的倒排索引和倒排索引位运算的方式,使得计算复杂度由原来的 2n 降至 n**,且算法稳定性有非常好的保证。其中列的倒排索引是对每列的值和所分布的行 ID (即 Posting List) 建立 KV 关系,倒排索引位运算是对符合条件的列倒排索引进行列间的位运算,即通过联合查询以便快速找到符合条件的规则行。

算法详细设计

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

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

38b07b2e-902a-11ed-bfe3-dac502259ad0.png

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

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

38d8b4ea-902a-11ed-bfe3-dac502259ad0.png

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

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

38eac7ac-902a-11ed-bfe3-dac502259ad0.png

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

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

392a8338-902a-11ed-bfe3-dac502259ad0.png

复杂度分析

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

3970defa-902a-11ed-bfe3-dac502259ad0.png

适用场景分析

回顾上面的设计方案我们可以看到,这种方式仅适用于 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

399ab9be-902a-11ed-bfe3-dac502259ad0.png

审核编辑 :李倩

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 索引
    +关注

    关注

    0

    文章

    60

    浏览量

    10846
  • Redis
    +关注

    关注

    0

    文章

    394

    浏览量

    12251
  • 位图
    +关注

    关注

    0

    文章

    6

    浏览量

    2481

原文标题:百万并发场景中倒排索引与位图计算的实践

文章出处:【微信号:OSC开源社区,微信公众号:OSC开源社区】欢迎添加关注!文章转载请注明出处。

收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    Java并发编程的“基石”——多线程概念初识

    万卡集群,每一秒都有数百个任务在排队、挂起、抢占资源。如果调度器出现毫秒级的延迟或死锁,意味着价值数百万的算力在空转。因此,算力调度系统对高并发、低延迟和绝对稳定性的要求,达到了苛刻的极点。这正是
    发表于 04-16 18:50

    微课-掌握Java并发编程的“基石”,入门并发编程

    处理并发请求的能力,直接等同于企业创造财富的速度。从双十一秒杀瞬间涌动的千亿级交易洪流,到春节期间十几亿人同时在线的红包雨,再到短视频平台每秒百万次的海量推荐计算,这些现象级商业成功的背后,绝非仅仅依靠几个精美的前端
    的头像 发表于 04-14 14:25 79次阅读

    Go 语言高并发服务设计与性能调优实战:从万级到百万并发的演进之路

    在2026年的今天,Go 语言已成为高并发后端服务的首选语言。根据 Stack Overflow 最新开发者调查: 指标 数据 Go 语言采用率 后端服务占比 42% 平均并发能力 单节点
    发表于 02-18 19:19

    一文说透了如何实现单片机的多任务并发

    在嵌入式系统开发,多任务并发是非常常见的,对于处理复杂的应用场景、提升系统的并发能力、提高系统的实时性等方面都有很大好处。在单片机实现多
    发表于 01-06 06:46

    桂花网M1000:轻量型蓝牙网关的场景落地与客户实践

    特性直接决定了场景边界: 连接能力:支持蓝牙 4.x,无遮挡环境覆盖 150 米,并发连接 20 台设备,扫描范围达上百台,适配中低设备密度场景; 传输保障:4G Cat.1 与 Wi-Fi 双模回传
    发表于 11-12 16:59

    工业物联网数据台的高并发性有什么作用

    工业物联网数据台的高并发性是保障其在复杂工业场景下稳定运行的核心能力之一。它的核心作用是确保大量设备同时接入和数据传输时,系统依然能高效处理、不卡顿、不丢失数据,能够在单位时间内高效处理海量设备
    的头像 发表于 10-28 11:28 385次阅读
    工业物联网数据<b class='flag-5'>中</b>台的高<b class='flag-5'>并发</b>性有什么作用

    8784芯片点位图资料

    电子发烧友网站提供《8784芯片点位图资料.pdf》资料免费下载
    发表于 10-10 17:07 1次下载

    软国际鸿蒙生态“应用+智慧场景”的创新实践

    论坛上,软国际智能物联网业务集团解决方案经理方彬受邀出席,发表“鸿蒙重构全场景阅读,开启融媒体行业全新体验”主题演讲,以融媒体APP解决方案为例,分享软国际鸿蒙生态“应用+智慧场景
    的头像 发表于 09-03 17:01 1263次阅读

    智慧农业新基建:边缘计算网关在精准农业的落地实践案例

    智慧农业新基建:边缘计算网关在精准农业的落地实践案例 传统农业生产中,水肥管理依赖经验判断,往往造成资源浪费和产量不稳定;同时,恶劣的自然环境也给农业生产带来诸多挑战。而蓝蜂边缘计算
    的头像 发表于 08-22 15:18 754次阅读

    Nginx高并发优化方案

    作为一名在生产环境摸爬滚打多年的运维工程师,我见过太多因为Nginx配置不当导致的性能瓶颈。今天分享一套完整的Nginx高并发优化方案,帮助你的系统从10万QPS突破到百万级别。
    的头像 发表于 08-13 15:51 1209次阅读

    软国际全场景AI实践

    近日,软国际与华为云“同舟共济”战略合作8周年庆典暨“云智能行业赋能,全场景AI正当时”高峰论坛隆重举行,会上软国际副总裁、AI研究院院长万如意博士发表了题为《软国际全
    的头像 发表于 07-24 16:32 1179次阅读

    Linux网络管理的关键技术和最佳实践

    在大型互联网企业,Linux网络管理是运维工程师的核心技能之一。面对海量服务器、复杂网络拓扑、高并发流量,运维人员需要掌握从基础网络配置到高级网络优化的全套技术栈。本文将结合大厂实际场景,深入解析Linux网络管理的关键技术和
    的头像 发表于 07-09 09:53 1114次阅读

    第三届大会回顾第3期 | FFRT并发框架在OpenHarmony的设计与实践

    演讲嘉宾 | 黄佑钟 回顾整理 | 廖   涛 排版校对 | 宋夕明 嘉宾介绍 开发框架分论坛  黄佑钟 ,海思Kirin解决方案并行与异构计算专家。 正文内容 多任务并发能更有效地利用CPU资源
    的头像 发表于 06-21 16:53 1455次阅读
    第三届大会回顾第3期 | FFRT<b class='flag-5'>并发</b>框架在OpenHarmony<b class='flag-5'>中</b>的设计与<b class='flag-5'>实践</b>

    鸿蒙5开发宝藏案例分享---应用并发设计

    ?** 鸿蒙并发编程实战指南:解锁ArkTS多线程黑科技** 嘿,开发者朋友们! 今天给大家扒一扒鸿蒙官方文档里藏着的并发编程宝藏—— 100+实战场景解决方案 !从金融理财到游戏开发,从折叠屏适配
    发表于 06-12 16:19

    手把手教你如何调优Linux网络参数

    在高并发网络服务场景,Linux内核的默认网络参数往往无法满足需求,导致性能瓶颈、连接超时甚至服务崩溃。本文基于真实案例分析,从参数解读、问题诊断到优化实践,手把手教你如何调优Lin
    的头像 发表于 05-29 09:21 1180次阅读