一、索引及压缩机制

### --- 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就是该表中对应的行是否有该维度的值

|NO.Z.00011|————|BigDataEnd|——|Hadoop&OLAP_Druid.V11|——|Druid.v11|架构|索引压缩机制|_取值

七、以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