Clickhouse RoaringBitmap

https://blog.csdn.net/penriver/article/details/119736050
https://juejin.cn/post/7179956435806076988

BitMap适合连续密集的正整数存储,对于稀疏的正整数存储,其性能在很多时候是没办法和int数组相比的,尤其是正整数跨度较大的场景;RoaringBitMap就是为了解决这个问题产生。

1 RoaringBitmap

1.1 介绍

RoaringBitmap是高效压缩位图,简称RBM
官网介绍:Roaring bitmaps are compressed bitmaps. They can be hundreds of times faster.

RBM的历史并不长,它于2016年由S. Chambi、D. Lemire、O. Kaser等人在论文《Better bitmap performance with Roaring bitmaps》与《Consistently faster and smaller compressed bitmaps with Roaring》中提出.

1.3 存储性能

https://zhuanlan.zhihu.com/p/616558669

1、连续数据

分别向位图中插入1w、10w、100w、1000w条连续数据,并且对比BitMap和RoaringBitMap占用空间的大小。比较结果如下表所示:

10w数据占用空间 100w数据占用空间 1000w数据占用空间
BitMap 97.7KB 976.6KB 9.5MB
RoaringBitMap 16KB 128KB 1.2MB

2、稀疏数据

我们知道,位图所占用空间大小只和位图中索引的最大值有关系,现在我们向位图中插入1和999w两个偏移量位的元素,再次对比BitMap和RoaringBitMap所占用空间大小。

占用空间
BitMap 9.5MB
RoaringBitMap 24Byte

1.4 读取性能

Roaring Bitmap压缩算法简介
Roaring Bitmap数据结构是将32位整型(INT)数划分为高16位和低16位。其中,高16位被划分为多个数据块(Chunk),低16位使用一个容器(Container)来存放,因此每个数据块最多能够存储2^16个整数。Roaring Bitmap将这些容器保存在一个动态数组中,按照高16位进行排序,可以通过高16位二分查找快速定位对应的容器。根据数据特征,使用三种不同的容器进行存储

  • 数组容器(Array Container):存储稀疏的数据,整数较为分散且不连续的情况。若容器里的最大数据小于4096,则使用数组容器来存储值。

  • 位图容器(Bitmap Container):存储稠密的数据,有很多连续的整数存在的情况。若容器里的最大数据大于等于4096,则使用位图容器来存储值。

  • 运行容器(Run Container): 存储连续值较多的数据。Run Container只有在其存储空间大小同时小于Array Container和Bitmap Container时才会被使用。

采用这种存储结构,Roaring Bitmap极大地提高了数据的压缩率,并且可以快速检索一个特定的值。在做位图计算(AND,OR,XOR)时,Roaring Bitmap提供了相应的算法来高效地实现在三种容器之间的运算。使得Roaring Bitmap无论在存储和计算性能上都变得优秀。

更多关于Roaring Bitmap的介绍信息,请参见Roaring Bitmap官方网站。

增删改查的时间复杂度方面,BitmapContainer只涉及到位运算且可以根据下标直接寻址,显然为O(1)。而ArrayContainer和RunContainer都需要用二分查找在有序数组中定位元素,故为O(logN)。

  • ArrayContainer一直线性增长,在达到4096后就完全比不上BitmapContainer了
  • BitmapContainer是一条横线,始终占用8kb
  • RunContainer比较奇葩,因为和数据的连续性关系太大,因此只能画出一个上下限范围。不管数据量多少,下限始终是4字节;上限在最极端的情况下可以达到128kb。
    空间占用(即序列化时写出的字节流长度)方面,BitmapContainer是恒定为8KB的。ArrayContainer的空间占用与基数(c)有关,为(2 + 2c)B;RunContainer的则与它存储的连续序列数(r)有关,为(2 + 4r)B。
    在这里插入图片描述

1.5 与bitmap的性能对比

roaringbitmap除了比bitmap占用内存少之外,其并集和交集操作的速度也要比bitmap的快,原因如下:

  • 计算上的优化
    对于roaringbitmap本质上是将大块的bitmap分成各个小块,其中每个小块在需要存储数据的时候才会存在。所以当进行交集或并集运算的时候,roaringbitmap只需要去计算存在的一些块而不需要像bitmap那样对整个大的块进行计算。如果块内非常稀疏,那么只需要对这些小整数列表进行集合的 AND、OR 运算,这样的话计算量还能继续减轻。这里既不是用空间换时间,也没有用时间换空间,而是用逻辑的复杂度同时换取了空间和时间。

同时在roaringbitmap中32位长的数据,被分割成高 16 位和低 16 位,高 16 位表示块偏移,低16位表示块内位置,单个块可以表达 64k 的位长,也就是 8K 字节。这样可以保证单个块都可以全部放入 L1 Cache,可以显著提升性能

  • 程序逻辑上的优化
    • roaringbitmap维护了排好序的一级索引以及有序的arraycontainer,当进行交集操作的时候,只需要根据一级索引中对应的值来获取需要合并的容器,而不需要合并的容器则不需要对其进行操作直接过滤掉。
    • 当进行合并的arraycontainer中数据个数相差过大的时候采用基于二分查找的方法对arraycontainer求交集,避免不必要的线性合并花费的时间开销。
    • roaingbitmap在做并集的时候同样根据一级索引只对相同的索引的容器进行合并操作,而索引不同的直接添加到新的roaringbitmap上即可,不需要遍历容器。
    • roaringbitmap在合并容器的时候会先预测结果,生成对应的容器,避免不必要的容器转换操作。

1.6 针对long整数的扩展【64-bit integers (long)】

虽然RoaringBitmap是为32位的情况设计的,但对64位整数进行了扩展。为此提供了两个类:Roaring64NavigableMap和Roaring64Bitmap。

Roaring64NavigableMap依赖于传统的红黑树。键是32位整数,代表元素中最重要的32位,而树的值是32位RoaringBitmap。32位RoaringBitmap表示一组元素的最低有效位。
较新的Roaring64Bitmap方法依赖ART数据结构来保存键/值对。键由元素的最重要的48位组成,而值是16位的Roaring容器。它的灵感来自 The Adaptive Radix Tree: ARTful Indexing for Main-Memory Databases by Leis et al. (ICDE '13)。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/222702.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

架构设计系列之常见架构(一)

本部分对常见架构进行简单的说明。 一、三层架构之经典 MVC 经典的 MVC 架构(Model-View-Controller)架构是软件系统架构设计中的经典,它将应用程序分为三个主要部分: 模型(Model)视图(View&…

智能优化算法应用:基于差分进化算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用:基于差分进化算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于差分进化算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.差分进化算法4.实验参数设定5.算法结果6.…

DC-3靶场

DC-3 DC-3靶场链接:https://download.vulnhub.com/dc/DC-3-2.zip 下载后解压会有一个DC-3.ova文件,直接在vm虚拟机点击左上角打开-->文件--.选中这个.ova文件就能创建靶场,kali和靶机都调整至NAT模式 首先进行主机发现: arp…

基于java的医院住院管理系统的设计与实现论文

摘 要 互联网发展至今,无论是其理论还是技术都已经成熟,而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播,搭配信息管理工具可以很好地为人们提供服务。针对医院住院信息管理混乱,出错率高,信息安全性差…

Vue学习笔记-Vue3中的customRef

作用 创建一个自定义的ref&#xff0c;并对其依赖项的更新和触发进行显式控制 案例 描述&#xff1a;向输入框中输入内容&#xff0c;在下方延迟1秒展示输入内容 代码&#xff1a; <template><input type"text" v-model"keyword"><h3&…

网络安全项目实战(四)--报文检测

8. TCP/UDP 段 目标 了解 TCP 段头的组织结构了解 UDP 段头的组织结构掌握 TCP/UDP 段的解析方式 8.1. UDP 段格式 下图是UDP的段格式&#xff08;该图出自[TCPIP]&#xff09;。 8.2. UDP头部 //UDP头部&#xff0c;总长度8字节// /usr/include/linux/udp.h struct udphdr …

自定义Axure元件库及原型图泳道图的绘制(详细不同类的案例)

目录 前言 一.自定义元件库 1.1 自定义元件库的作用 1.2 自定义元件的操作 二.流程图 2.1 流程图的作用 2.2 绘制流程图 2.3 简易流程图案例 三.泳道图 3.1 泳道图的作用 3.2 流程图和泳道图的区别 3.3 绘制泳道图 四.绘制前的准备 五.案例 4.1 门诊模块案例 4.2 …

聚观早报 |iOS17.3引入设备被盗保护;iPhone16或调整设计

【聚观365】12月14日消息 iOS17.3引入设备被盗保护 iPhone16或调整设计 马斯克星链网络使用量飙升 华为鸿蒙智行App正式上线 特斯拉人形机器人Optimus二代上线 iOS17.3引入设备被盗保护 苹果向iPhone用户推送了iOS17.3开发者预览版Beta更新&#xff0c;本次更新距离上次发…

Vue2.x源码:new Vue()做了啥

例子1new Vue做了啥?new Vue做了啥,源码解析 initMixin函数 初始化 – 初始化Vue实例的配置initLifecycle函数 – 初始化生命周期钩子函数initEvents – 初始化事件系统初始化渲染 initRender初始化inject选项 例子1 <div id"app"><div class"home&…

docker安装最新版SQL Server并还原备份的数据库

docker安装数据库 拉取微软官方最新版镜像 docker pull mcr.microsoft.com/mssql/server 拉去镜像并创建容器 docker run -e "ACCEPT_EULAY" -e "SA_PASSWORDsa_password_123456" -p 1433:1433 -v /opt/:/opt --name sqlserver -d mcr.microsoft.com/ms…

前端页面显示的时间格式为:2022-03-18T01:46:08.000+00:00 如何转换为:年-月-日,并根据当前时间判断为几天前

由于后端每条博文的发表时间是以“xxxx—xx—xxxx:xx:xx”的形式显示的&#xff0c; 现在要在前端改成“xxxx年xx月xx日”的形式。 并对10分钟内发表的显示“刚刚”&#xff0c;对24小时内发表的显示“小时前”。 超过24小时&#xff0c;小于48小时&#xff0c;显示“1天前”。…

生产实践:基于K8S的私有化部署解决方案

随着国内数字化转型的加速和国产化进程推动&#xff0c;软件系统的私有化部署已经成为非常热门的话题&#xff0c;因为私有化部署赋予了企业更大的灵活和控制权&#xff0c;使其可以根据自身需求和安全要求定制和管理软件系统。下面分享下我们的基于k8S私有化部署经验。 私有化…

Nginx 服务器安装及配置文件详解

1. 安装nginx 1.1 选择稳定版本 我们编译安装nginx来定制自己的模块&#xff0c;机器CentOS 6.2 x86_64。首先安装缺少的依赖包&#xff1a; # yum -y install gcc gcc-c make libtool zlib zlib-devel openssl openssl-devel pcre pcre-devel 这些软件包如果yum上没有的话…

VS2022配置C++ 20解决import std报错

C 20新特征支持用import std来导入std模块&#xff0c;如下&#xff1a; 配置时主要有两个步骤&#xff1a; &#xff08;1&#xff09;项目--属性--常规--C语言标准--预览 - 最新 C 工作草案中的功能 (/std:clatest) 注意选择ISO C20 标准 (/std:c20)也不能正常使用&#xf…

【PgSQL】导出表结构为EXCEL

详细SQL语句&#xff1a; C.relname ‘你的表名’ 直接输入表面即可 PgSQL 打印表结构语句 SELECT C.relname AS "表名",CAST(obj_description(C.oid, pg_class) AS VARCHAR) AS "表名描述",A.attname AS "字段名",CASE WHEN A.attnotnull f …

(C++)无重复字符的最长子串--滑动窗口

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台备战技术面试&#xff1f;力扣提供海量技术面试资源&#xff0c;帮助你高效提升编程技能&#xff0c;轻松拿下世界 IT 名企 Dream Offer。https://le…

Oracle存储过程打印输出错误信息、行号,快速排查

测试存储过程如下&#xff1a; create or replace procedure prc_test isp_1 varchar2(2); beginp_1 : lxw测试;exceptionwhen others thendbms_output.put_line(sqlcode); --Oracle内置变量&#xff0c;错误代码dbms_output.put_line(sqlerrm); --Oracle内置变量&#xff0c;…

【SpringBoot篇】基于布隆过滤器,缓存空值,解决缓存穿透问题 (商铺查询时可用)

文章目录 &#x1f354;什么是缓存穿透&#x1f384;解决办法⭐缓存空值处理&#x1f388;优点&#x1f388;缺点&#x1f38d;代码实现 ⭐布隆过滤器&#x1f38d;代码实现 &#x1f354;什么是缓存穿透 缓存穿透是指在使用缓存机制时&#xff0c;大量的请求无法从缓存中获取…

KylinV10 将项目上传至 Github

KylinV10 将项目上传至 Github 银河麒麟操作系统 V10 是在 Ubuntu 的基础上开发的&#xff0c;所以适用于 Ubuntu 的也适用于 KylinV10 一般上传至 GitHub&#xff0c;有两种方式&#xff0c;一种是 HTTPS&#xff0c;一种是 SSH&#xff0c;但是在 KylinV10 操作系统 HTTPS 的…

Android camera的metadata

一、实现 先看一下metadata内部是什么样子&#xff1a; 可以看出&#xff0c;metadata 内部是一块连续的内存空间。 其内存分布大致可概括为&#xff1a; 区域一 &#xff1a;存 camera_metadata_t 结构体定义&#xff0c;占用内存 96 Byte 区域二 &#xff1a;保留区&#x…