大量数据检索问题

10亿数据存储检索

数据检索问题:
给定一个长度为10 的int数组,例如:{1,2,3,4,5,6,7,8,9,10} 查找数字“9” 是否存在给定数组中。对于这样的问题直接进行数组遍历或者二分查找很容易就找到对应数字是否存在,但这是数据量很少的情况。计算一下数组占用存储空间:10个int数字4字节=40字节。
同样的问题数组长度换成10亿int数组,占用空间10亿
4字节=40亿字节=4000000000/1024/1024/1024=3.73GB,这样的空间占用内存无法支持只能存盘进行分批读取,不可行

bitmap进行大量数据存储检索

bitmap:使用位来存储true/false 来表示这个位上是否存在数字

这样就表示数组:{1,3,7} 此时空间占用只是8bit,可以使用1bit表示1个数字,相对于int类型数据使用4byte=4*8bit=32bit 表示1个int类型数据来说,空间减少32倍。
可得:10亿数据=4000000000/1024/1024/32=119MB,可以使用一个10亿个bit的数组进行存储检索,切检索复杂度为常数。占用空间减少32倍

非连续数据空间占用问题

上面讲的10亿数据可以理解为全部非bit位都被占用,无空间浪费。但是bit数组是根据存储数据的最大值进行空间划分,存在如下情况:数组{1,2,999999999} 只存在三个数字,如果直接使用int数组存储空间占用:4*3=12字节,但是如果使用bitmap存储,根据最大数值划分空间,依然占用119MB。这种情况就造成空间极大浪费。
针对这种情况:
1、业务上根据情况决定使用那种存储方式
2、技术上还可以针对这种空间浪费情况进行优化,压缩存储。使用压缩位图(RoaringBitmap)的方式。

RoaringBitmap

简介

RBM 其实就是相对于bitmap的优化版本,能提供更优秀的压缩性能和更快的查询效率。
基于其优秀的压缩方式和查询效率,已经有很多开源项目在使用

  • Apache Lucene
  • Apache Druid
  • Apache Spark
  • Apache CarbonData
  • LinkedIn Pinot
  • Apache Kylin
    并且提供了多种语言的实现方式

Java 使用示例

// 添加依赖<dependency><groupId>org.roaringbitmap</groupId><artifactId>RoaringBitmap</artifactId><version>0.9.10</version></dependency>
 public static void main(String[] args) {RoaringBitmap roaringBitmap = RoaringBitmap.bitmapOf(1,2,3,1000);RoaringBitmap roaringBitmap1 = new RoaringBitmap();roaringBitmap1.add(4000L,4005L);System.out.println("third num:"+roaringBitmap.select(3));System.out.println("num 2 sort key:"+roaringBitmap.rank(2));System.out.println("is contains 1000 num:"+roaringBitmap.contains(1000));System.out.println("is contains 1001 num:"+roaringBitmap.contains(1001));//对比占用空间大小RoaringBitmap roaringBitmap2 = new RoaringBitmap();byte[] bits = new byte[1000000];List<Integer> list = new ArrayList<Integer>();for (int i = 0; i < 1000000; i++) {roaringBitmap2.add(i);bits[i] = (byte) i;list.add(i);}System.out.println((byte)100);System.out.println("roaringbitmap size:"+ ObjectSizeCalculator.getObjectSize(roaringBitmap2));System.out.println("byte size:"+ObjectSizeCalculator.getObjectSize(bits));System.out.println("list size:"+ObjectSizeCalculator.getObjectSize(list));}

结果:
一百万数据不同方式占用存储空间

RoaringBitmap 原理

为什么存储空间能相对节约这么多?主要看数据存储结构

每个RoaringBitmap 包含一个RoaringArray,叫做highLowContainer 包含了所有数据

hightLowContainer 包含三个参数
keys、values、size:
每个32位的整形,高16位会被作为key存储到char[] keys中,低16位则被看做value,存储到Container[] values中的某个Container中。keys和values通过下标一一对应。size则标示了当前包含的key-value pair的数量,即keys和values中有效数据的数量。
针对这样的结构,数据插入逻辑如下:

抽象展示:

1、821697800 对应的 16 进制数为 30FA1D08, 其中高 16 位为 30FA, 低16位为 1D08。
2、我们先用二分查找从一级索引(即 Container Array)中找到数值为 30FA 的容器(如果该容器不存在,则新建一个),从图中我们可以看到,该容器是一个 Bitmap 容器。
3、找到了相应的容器后,看一下低 16 位的数值 1D08,它相当于是 7432,因此在 Bitmap 中找到相应的位置,将其置为 1 即可。

三种存储container

ArrayContainer

Array Container 是 Roaring Bitmap 初始化默认的 Container。Array Container 适合存放稀疏的数据,其内部数据结构是一个有序的 Short 数组。数组初始容量为 4,数组最大容量为 4096,所以 Array Container 是动态变化的,当容量不够时,需要扩容,并且当超过最大容量 4096 时,就会转换为 Bitmap Container。由于数组是有序的,存储和查询时都可以通过二分查找快速定位其在数组中的位置。

bitmapContainer

第二种 Container 是 Bitmap Container。它的数据结构是一个 Long 数组,数组容量恒定为 1024,和上文的 Array Container 不同,Array Container 是一个动态扩容的数组。Bitmap Container 不用像 Array Container 那样需要二分查找定位位置,而是可以直接通过下标直接寻址。

由于每个 Bitmap Container 需要处理低 16 位数据,也就是需要使用 Bitmap 来存储需要 8192 B(2^16/8), 而一个 Long 值占 8 个 B,所以数组大小为 1024。因此一个 Bitmap Container 固定占用内存 8 KB。

RunContainer

RunContainer中的Run指的是行程长度压缩算法(Run Length Encoding),对连续数据有比较好的压缩效果。

它的原理是,对于连续出现的数字,只记录初始数字和后续数量。即:

对于数列11,它会压缩为11,0;
对于数列11,12,13,14,15,它会压缩为11,4;
对于数列11,12,13,14,15,21,22,它会压缩为11,4,21,1;
源码中的short[] valueslength中存储的就是压缩后的数据。

这种压缩算法的性能和数据的连续性(紧凑性)关系极为密切,对于连续的100个short,它能从200字节压缩为4字节,但对于完全不连续的100个short,编码完之后反而会从200字节变为400字节。

如果要分析RunContainer的容量,我们可以做下面两种极端的假设:

最好情况,即只存在一个数据或只存在一串连续数字,那么只会存储2个short,占用4字节
最坏情况,0~65535的范围内填充所有的奇数位(或所有偶数位),需要存储65536个short,128kb

不同存储模式


三种存储方式对比:
1,

一文了解RoaringBitmap相关推荐

  1. 生产实践中的经典算法(四)-BitMap

    生产实践中的经典算法(四)-BitMap 1.BitMap的原理 位图(Bitmap),即位(Bit)的集合,是一种数据结构,可用于记录大量的0-1状态,在很多地方都会用到,比如Linux内核(如in ...

  2. java面试题集中了好几篇的搜索的

    1.servlet执行流程 客户端发出http请求,web服务器将请求转发到servlet容器,servlet容器解析url并根据web.xml找到相对应的servlet,并将request.resp ...

  3. roaringbitmap java,BitMap、RoaringBitmap与JavaEWAH

    本文主要介绍BitMap的算法思想,以及开源工具类JavaEWAH.RoaringBitmap的简单用法. 一.BitMap 介绍 BitMap使用bit位,来标记元素对应的Value.该算法能够节省 ...

  4. 【java】高效压缩位图RoaringBitmap的原理与应用

    文章目录 1.概述 2.位图法简述 3.RoaringBitmap的思路 4.Container原理 4.1 ArrayContainer 4.2 BitmapContainer 4.3 RunCon ...

  5. arcpy实现空间查询_「实战系列」GP+Roaringbitmap,亿级会员十万级标签毫秒级查询...

    在大数据处理和应用场景中经常需要从亿级甚至十亿级会员中搜索出符合特定标签的会员.很多企业都会使用 HBase 或者 Hive + Hadoop 的方式,这样的方式查询效率非常慢,在标签非常多的情况下计 ...

  6. RoaringBitmap 原理

    前言 位图索引被广泛用于数据库和搜索引擎中,通过利用位级并行,它们可以显著加快查询速度.但是,位图索引会占用大量的内存,因此我们会更喜欢压缩位图索引. Roaring Bitmaps 就是一种十分优秀 ...

  7. 高效压缩位图RoaringBitmap的原理与应用

    目录 位图法简述 RoaringBitmap的思路 Container原理 ArrayContainer BitmapContainer RunContainer 时空分析 Container的创建与 ...

  8. 一文搞定ClickHouse在苏宁用户画像场景的实践(建议收藏)

    关注公众号,获取更多一线大厂最新资讯! 摘要:今天分享的主要内容是ClickHouse在苏宁用户画像场景的实践 分享时间:2021年5月26日 内容分享:杨兆辉 摘要整理:皮卡丘 主要内容: 苏宁如何 ...

  9. 伍六七带你学算法 入门篇-最长回文串

    力扣解题,每日一题:409. 最长回文串 难度- 简单 给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串. 在构造过程中,请注意区分大小写.比如 "Aa" ...

  10. 导出swagger2生成的文档

    百度了好多篇用法,没法用.特此记录一下 一.下载项目 下载https://github.com/Swagger2Markup/spring-swagger2markup-demo下的项目,保存,注意文 ...

最新文章

  1. 基于hi-nginx的web开发(python篇)——路由装饰器
  2. Python爬虫入门(6):Cookie的使用
  3. iTween基础之功能简介
  4. python运行界面英文翻译_python使用百度api翻译中英文
  5. 【转】【UML】使用Visual Studio 2010 Team System中的架构师工具(设计与建模)
  6. 【剑指offer】_05 连续子数组最大和
  7. 先来先服务算法、运行时间最短者优先算法和最高响应比优先调度算法_Linux进程调度:完全公平调度器CFS
  8. java 约瑟夫环_java中约瑟夫环代码实现
  9. eviews建立时间序列模型_模型建立——时间序列 eviews协整检验(EG两步法(Engle-Granger))...
  10. 怎么下载网页在线视频
  11. [填坑] 解决 Ubuntu ssh 登录自动休眠问题
  12. Flutter时间日期格式化等操作(一个月的最后一天日期,时间段内所有日期...)
  13. windows环境开发,使用hbase报错。Could not locate executablenull\bin\winutils.exe in the Hadoop binaries
  14. 用HTML制作简单的个人介绍主页
  15. LoadRunner--并发测试(多用户)
  16. Delphi中,如何读取资源文件?
  17. EasyCVR出现只有HLS协议可播放,其他协议均无法播放是什么原因?
  18. 2021年安全员-C证(江西省)考试报名及安全员-C证(江西省)证考试
  19. ghost系统之家Ghost XP SP3加强版V8.0_2010.4[NTFS版]
  20. 三星s7edge手机无法连接adb问题

热门文章

  1. 泰坦尼克号python数据分析统计服_Kaggle入门级赛题:泰坦尼克号生还者预测——数据分析篇...
  2. 深大uooc大学生心理健康章节答案第二章
  3. html 6位数支付密码,支付宝支付密码怎么设置长密码 支付宝支付密码取消6位数字密码设置长密码的方法...
  4. 支付宝小程序设置服务器维护,支付宝小程序配置
  5. win10去掉快捷方式小箭头_快捷方式小箭头很烦人 一招教你取消
  6. nginx代理内网服务器的图片服务器
  7. 从0开发豆果美食小程序——tag组件
  8. 从hr口中了解react的状态管理库(mobx, recoil), 立马过来学习之mobx
  9. 九、【服务器】服务器硬件名称中英文汇总2
  10. Ceres-Solver