|NO.Z.00011|——————————|BigDataEnd|——|Hadoop&OLAP_Druid.V11|——|Druid.v11|架构|索引压缩机制|
一、索引及压缩机制
### --- Druid的查询时延低性能好的主要是因为采用了五个技术点:
~~~ 数据预聚合
~~~ 列式存储、数据压缩
~~~ Bitmap 索引
~~~ mmap(内存文件映射方式)
~~~ 查询结果的中间缓存
二、数据聚合
### --- 数据预聚合
~~~ Druid通过一个roll-up的处理,将原始数据在注入的时候就进行汇总处理
~~~ Roll-up可以压缩我们需要保存的数据量
~~~ Druid会把选定的相同维度的数据进行聚合操作,可减少存储的大小
~~~ Druid可以通过 queryGranularity 来控制注入数据的粒度。
~~~ 最小的queryGranularity 是 millisecond(毫秒级)
三、Roll-up聚合前:
time APPKey area value 2020-10-05 10:00:00 areakey1 Beijing 1 2020-10-05 10:30:00 areakey1 Beijing 1 2020-10-05 11:00:00 areakey1 Beijing 1 2020-10-05 11:00:00 areakey1 Beijing 2
四、Roll-up聚合后:
time | AppKey | area | value |
2020-10-05 | areakey1 | Beijing | 3 |
2020-10-05 | areakey2 | Shanghai | 2 |
五、位图索引
Time | AppKey | Area | Value |
2020-10-01 10:00:00 | appkey1 | 深圳 | 1 |
2020-10-01 11:00:00 | appkey2 | 北京 | 1 |
2020-10-01 12:00:00 | appkey2 | 深圳 | 1 |
2020-10-01 13:00:00 | appkey2 | 北京 | 1 |
… … | … … | … … | … … |
2020-10-01 23:00:00 | appkey3 | 北京 | 1 |
### --- 位图索引
~~~ # Druid在摄入的数据示例:
~~~ 第一列为时间,Appkey和Area都是维度列,Value为指标列
~~~ Druid会在导入阶段自动对数据进行Rollup,将维度相同组合的数据进行聚合处理
~~~ 数据聚合的粒度根据业务需要确定
六、按天聚合后的数据如下:
Time | AppKey | Area | Value |
2020-10-01 | appkey1 | 北京 | 10 |
2020-10-01 | appkey1 | 深圳 | 20 |
2020-10-01 | appkey2 | 北京 | 30 |
2020-10-01 | appkey2 | 深圳 | 40 |
2020-10-01 | appkey3 | 北京 | 50 |
2020-10-01 | appkey3 | 深圳 | 60 |
### --- Druid通过建立位图索引,实现快速数据查找。
~~~ Bitmap 索引主要为了加速查询时有条件过滤的场景。
~~~ Druid 在生成索引文件的时候,对每个列的每个取值生成对应的 Bitmap 集合。如下图所示:
Key | ||||||
appkey1 | 1 | 1 | 0 | 0 | 0 | 0 |
appkey2 | 0 | 0 | 1 | 1 | 0 | 0 |
appkey3 | 0 | 0 | 0 | 0 | 1 | 1 |
深圳 | 0 | 1 | 0 | 1 | 0 | 1 |
北京 | 1 | 0 | 1 | 0 | 1 | 0 |
### --- 索引位图可以看作是HashMap<String, Bitmap>
~~~ key就是维度的取值
~~~ value就是该表中对应的行是否有该维度的值

七、以SQL查询为例:
### --- boolean条件查询
select sum(value) from tab1
where time='2020-10-01'
and appkey in ('appkey1', 'appkey2') and area='北京'
~~~ # 执行过程分析:
~~~ 根据时间段定位到segment
~~~ Appkey in ('appkey1', 'appkey2') and area='北京' 查到各自的bitmap
~~~ (appkey1 or appkey2) and 北京
~~~ (110000 or 001100) and 101010 = 111100 and 101010 = 101000
~~~ 符合条件的列为:第1行 & 第3行,这几行 sum(value) 的和为 40
### --- group by 查询
select area, sum(value) from tab1
where time='2020-10-01' and appkey in ('appkey1', 'appkey2')
group by area
### --- 该查询与上面的查询不同之处在于将符合条件的列
~~~ appkey1 or appkey2
~~~ 110000 or 001100 = 111100
~~~ 将第1行 到 第4行取出来
~~~ 在内存中做分组聚合。结果为:北京:40、深圳:60
Walter Savage Landor:strove with none,for none was worth my strife.Nature I loved and, next to Nature, Art:I warm'd both hands before the fire of life.It sinks, and I am ready to depart
——W.S.Landor
分类:
bdv024-druid
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」