druid 概述

1 什么样的业务适合用 Druid?

时序化数据:Druid 可以理解为时序数据库,所有的数据必须有时间字段。
实时数据接入可容忍丢数据(tranquility):目前 tranquility 有丢数据的风险,所以建议实时和离线一起用,实时接当天数据,离线第二天把今天的数据全部覆盖,保证数据完备性。
OLAP 查询而不是 OLTP 查询:Druid 查询并发有限,不适合 OLTP 查询。
非精确的去重计算:目前 Druid 的去重都是非精确的。
无 Join 操作:Druid 适合处理星型模型的数据,不支持关联操作。
数据没有 update 更新操作,只对 segment 粒度进行覆盖:由于时序化数据的特点,Druid 不支持数据的更新。

2 如何设置合理的 Granularity?

首先解释下 segmentGranularity 和 queryGranularity,前者是 segment 的组成粒度,后者是 segment 的聚合粒度。

queryGranularity  决定查询最小粒度,决定roll up粒度;
segmentGranularity  决定分块文件粒度;

要求 queryGranularity 小于等于 segmentGranularity,然后在数据导入时,按照下面的规则进行设置。 segmentGranularity(离线数据导入的设置):

导入的数据是天级别以内的:“hour”或者“day”。
导入的数据是天级别以上的:“day”。
导入的数据是年级别以上的:“month”。
需要说明的是,这里我们仅仅是简单的通过 intervals 进行 segmentGranularity 的设置,更加合理的做法应该是结合每个 segment 的大小以及查询的复杂度进行综合衡量。

考虑到 tranquility 实时任务的特殊性和数据的安全性,我们建议实时数据导入时,segmentGranularity 设置成“hour”。

queryGranularity:根据业务查询最小粒度和查询复杂度来定,假设查询只需要到小时粒度,则该参数设置为“hour”。

3 需要去重的维度到底需不需要定义到维度列中?

如果去重的维度只需要去重计算,没有其他的作用,譬如进行过滤或者作为分组字段,我们建议不要添加到维度列中,因为不添加的话,这样数据的预聚合效果更好。

4 druid底层技术

除了 MPP 架构外,它还运用到了四点重要的技术,分别是:

  • 预聚合

  • 列式存储

  • 字典编码

  • 位图索引

5  底层数据结构

https://blog.csdn.net/BeiisBei/article/details/107758269?share_token=c039acd0-fa51-4696-83ca-b50dfefacdd9

http://hbasefly.com/2018/06/19/timeseries-database-8/?jqdajo=dz6ta&jqrghm=hkl243&cmhmdi=6cwh03

三种数据结构

(1)一个字典:将值从字符串(所有的dimension列的数值都被当做字符串处理)映射到整数id
(2)一个值的列表(正排数据):把列中的数值通过字典编码以后,将数字id存储在列表里面
(3)一个bitmap倒排索引:对于列里面的每个不同的值,都对应存储为一个bitmap,用来表示哪一行数据包含该值

为什么我们需要这三种数据结构呢?
1.通过字典将字符串映射成数字id,数字id通常比字符串更小,因此可以被更紧凑的存储。
2.第三点中的bitmap,通常被称为倒排索引,用于支持快速的过滤操作(bitmap对AND和OR操作的速度非常快)。
3.最后,第二点中的值列表将用于支持group by和topN查询,而普通的查询只需要根据filter出来的行去来聚合相应的metirc就可以了,而不需要访问上述2中的值列表。

注意:bitmap跟其他两种数据结构不同,其他两种数据结构都是跟随数据量的增长而线性增长的(最差情况下),而 bitmap的大小=数据的总行数 * 列中值的种类数 (也就是字典的size)。这就意味着如果值得的种类很多,那么bitmap中为1的数量将会非常稀疏,这种情况下bitmap有可能被大幅压缩。Druid针对这种情况,采用了特殊的压缩算法,比如roaring bitmap压缩算法。

1.编码了列值的字典:
{
    'Justin Bieber': 0,
    'Ke$ha':         1
}
 
2.列值数据(正排):
[0, 0, 1, 1](第一个和第二个0代表第一,二行数据编码,即上述字典中的'Justin BieBer',第三个和第四个代表第三四行数据,即上述字典中的'Ke$ha')
 
3. Bitmaps:字典中的每个值对应一个bitmap
value='Justin Bieber': [1, 1, 0, 0]
value='Ke$ha': [0, 0, 1, 1]

6 roll up

 生产环境中,每天会有成百上千亿的原始数据(raw data)进入到Druid中,Druid最小粒度支持毫秒级别的事件,但是在一般使用场景中,我们很少会关注如此细粒度的数据集。

总结,roll-up对什么范围内的数据进行第一步的聚合,是由"queryGranularity" : "minute"来决定的。
queryGranularity:默认为None,允许查询的时间粒度,单位与segmentGranularity相同,如果为None那么允许以任意时间粒度进行查询。

注意:当设定roll-up为true时,会带来信息量的丢失,因为roll-up的粒度会变成最小的数据可视化粒度,即毫秒级别的原始数据,如果按照分钟粒度进行roll-up,那么入库之后我们能够查看数据的最小粒度即为分钟级别。

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值