Druid.io系列(二):基本概念与架构

在介绍Druid架构之前,我们先结合有关OLAP的基本原理来理解Druid中的一些基本概念。

1 数据
 Druidæ°æ®
以图3.1为例,结合我们在第一章中介绍的OLAP基本概念,按列的类型上述数据可以分成以下三类:

时间序列(Timestamp),Druid既是内存数据库,又是时间序列数据库,Druid中所有查询以及索引过程都和时间维度息息相关。Druid底层使用绝对毫秒数保存时间戳,默认使用ISO-8601格式展示时间(形如:yyyy-MM-ddThh:mm:sss.SSSZ,其中“Z”代表零时区,中国所在的东八区可表示为+08:00)。

维度列(Dimensions),Druid的维度概念和OLAP中一致,一条记录中的字符类型(String)数据可看作是维度列,维度列被用于过滤筛选(filter)、分组(group)数据。如图3.1中page、Username、Gender、City这四列。

度量列(Metrics),Druid的度量概念也与OLAP中一致,一条记录中的数值(Numeric)类型数据可看作是度量列,度量列被用于聚合(aggregation)和计算(computation)操作。如图3.1中的Characters Added、Characters Removed这两列。

2 上卷
生产环境中,每天会有成百上千亿的原始数据(raw data)进入到Druid中,Druid最小粒度支持毫秒级别的事件,但是在一般使用场景中,我们很少会关注如此细粒度的数据集,同时,对数据按一定规律进行聚合不仅可以节约存储空间,亦可获得更有价值的视图。所以与其他OLAP类产品一样,Druid也支持上卷(roll-up)操作。最常用的上卷操作是对时间维度进行聚合,比如对图3.2中的数据按照小时粒度进行聚合可以得到图3.3,图3.3相对于图3.2来说,显得更加直观,也更有助于分析人员掌握全局态势。不过,上卷操作也会带来信息量的丢失,因为上卷的粒度会变成最小数据可视化粒度,即毫秒级别的原始数据,如果按照分钟粒度进行roll-up,那么入库之后我们能够查看数据的最小粒度即为分钟级别。 

ä¸å·
3 分片
Druid是时间序列数据库,也存在分片(Sharding)的概念。Druid对原始数据按照时间维度进行分片,每一个分片称为段(Segment)。 
Segment是Druid中最基本的数据存储单元,采用列式(columnar)存储某一个时间间隔(interval)内某一个数据源(dataSource)的部分数据所对应的所有维度值、度量值、时间维度以及索引。

Segment数据结构

时间维度(绝对毫秒数)和度量值在底层使用整数(Integer)或者浮点数(floating point)数组进行压缩存储,默认采用LZ4压缩算法(可选LZF、uncompressed)。

维度列使用字典编码、位图索引以及相应压缩算法,包含如下三种数据结构,以图3.1中数据举例: 

segment
为什么使用这三种数据结构,它们有哪些优势:

使用字典编码可以减少字符串数据的存储空间,同时表达更加简便、紧凑;

位图索引,结构类似于倒排索引,可以快速地进行按位逻辑操作;

位图索引尺寸=列基数 *数据行数,对于高基数列,我们在第二章中也详细介绍了很多位图索引压缩算法,Druid中实现了Concisebitmap compression以及Roaring bitmap compression,默认使用Concise。

Segment存储结构 
Segment逻辑名称形如“datasource_intervalStart_intervalEnd_version_partitionNum”,:

dataSource:数据源;

intervalStart、intervalEnd:时间间隔的起止,使用ISO-8601格式;

version:版本号,默认v1,用于区分多次加载同一数据对应的Segment;

partitionNumber:分区编号,在每个时间间隔内,根据数据量的大小一个Segment内部可能会有多个分区,官方推荐通过控制时间间隔粒度或者partition的个数来保证每个partition的大小在300Mb-700Mb之间,从而获得最优的加载与查询性能。

è¿éåå¾çæè¿°

è¿éåå¾çæè¿°
4 集群节点
Druid集群包含多种节点类型,分别是Historical Node、Coordinator Node、Broker Node、Indexing Service Node(包括Overlord、MiddleManager和Peon)以及Realtime Node(包括Firehose和Plumber)。

Druid将整个集群切分成上述角色,有两个目的:第一,划分Historical Node和Realtime Node,是将历史数据的加载与实时流数据处理切割开来,因为二者都需要占用大量内存与CPU;第二,划分Coordinator Node和Broker Node,将查询需求与数据如何在集群内分布的需求切割开来,确保用户的查询请求不会影响数据在集群内的分布情况,从而不会造成数据“冷热不均”,局部过热,影响查询性能的问题。

图3.5给出了Druid集群内部的实时/批量数据流以及查询请求过程。我们可以看到,实时数据到达Realtime Node,经过Indexing Service,在时间窗口内的数据会停留在Realtime Node内存中,而时间窗口外的数据会组织成Segment存储到Deep Storage中;批量数据经过Indexing Service也会被组织成Segment存储到Deep Storage中,同时Segment的元信息都会被注册到元信息库中,Coordinator Nodes会定期(默认为1分钟)去同步元信息库,感知新生成的Segment,并通知在线的Historical Node去加载Segment,Zookeeper也会更新整个集群内部数据分布拓扑图。 

è¿éåå¾çæè¿°
当用户需要查询信息时,会将请求提交给Broker Node,Broker Node会请求Zookeeper获取集群内数据分布拓扑图,从而知晓请求应该发给哪些Historical Node以及Realtime Node,汇总各节点的返回数据并将最终结果返回给用户。 
在(三)中,我们将逐一介绍各类节点。
--------------------- 
作者:njpjsoftdev 
来源:CSDN 
原文:https://blog.csdn.net/njpjsoftdev/article/details/52955788 
版权声明:本文为博主原创文章,转载请附上博文链接!

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值