原文链接:  https://blog.csdn.net/njpjsoftdev/article/details/52955788

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

1 数据

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

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

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

  3. 度量列(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中数据举例: 

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

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

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

  3. 位图索引尺寸=列基数 *数据行数,对于高基数列,我们在第二章中也详细介绍了很多位图索引压缩算法,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,汇总各节点的返回数据并将最终结果返回给用户。 
在(三)中,我们将逐一介绍各类节点。

Druid.io系列(二):基本概念与架构的更多相关文章

  1. Druid.io系列(七):架构剖析

    1. 前言 Druid 的目标是提供一个能够在大数据集上做实时数据摄入与查询的平台,然而对于大多数系统而言,提供数据的快速摄入与提供快速查询是难以同时实现的两个指标.例如对于普通的RDBMS,如果想要 ...

  2. Druid.io系列(一):简介

    原文链接: https://blog.csdn.net/njpjsoftdev/article/details/52955676 Druid.io(以下简称Druid)是面向海量数据的.用于实时查询与 ...

  3. Druid.io系列(九):数据摄入

    1. 概述 Druid的数据摄入主要包括两大类: 1. 实时输入摄入:包括Pull,Push两种 - Pull:需要启动一个RealtimeNode节点,通过不同的Firehose摄取不同种类的数据源 ...

  4. Druid.io系列(五):查询过程

    原文链接: https://blog.csdn.net/njpjsoftdev/article/details/52956194 Druid使用JSON over HTTP 作为底层的查询语言,不过强 ...

  5. SpringCloud系列二:Restful 基础架构(搭建项目环境、创建 Dept 微服务、客户端调用微服务)

    1.概念:Restful 基础架构 2.具体内容 对于 Rest 基础架构实现处理是 SpringCloud 核心所在,其基本操作形式在 SpringBoot 之中已经有了明确的讲解,那么本次为 了清 ...

  6. Druid.io系列(八):部署

    介绍 前面几个章节对Druid的整体架构做了简单的说明,本文主要描述如何部署Druid的环境 Imply提供了一套完整的部署方式,包括依赖库,Druid,图形化的数据展示页面,SQL查询组件等.本文将 ...

  7. Druid.io系列(三): Druid集群节点

    原文链接: https://blog.csdn.net/njpjsoftdev/article/details/52955937 1 Historical Node Historical Node的职 ...

  8. ELK系列二:Elasticsearch的架构原理和配置优化

    1.Elasticsearch的数据组织架构 1.1.Elasticsearch结构概念 集群(cluster):拥有相同cluster-name的elasticsearch结点的集合(每个结点其实就 ...

  9. Druid.io系列(六):问题总结

    原文地址: https://blog.csdn.net/njpjsoftdev/article/details/52956508 我们在生产环境中使用Druid也遇到了很多问题,通过阅读官网文档.源码 ...

随机推荐

  1. java集合运算:求交集,并集,集合差

    今天突然想用Java实现如何用集合实现交集,并集和差集的运算了!主要是看Python语言的时候想起来的. 实现主要使用的Set集合,Set集合的特点是集合内的元素不可重复. 具体代码如何: packa ...

  2. Android程序员学WEB前端(1)-HTML(1)-标准结构常用标签-Sublime

    转载请注明出处:http://blog.csdn.net/iwanghang/article/details/76522043觉得博文有用,请点赞,请评论,请关注,谢谢!~ 8月份了,换工作有2个月了 ...

  3. MPAndroidChart Wiki(译文)~Part 6

    22. ViewPortHandler ViewPortHandler负责处理图表的视窗.也就是说它负责图表视图中的展示给用户的那部分内容.包括图表位移,缩放级别,图表大小和绘制区域以及当前偏移量.V ...

  4. Android Studio 默认 debug.keystore , apk打包,keystore.jks文件生成,根据keystore密钥获取SHA1安全码

    参考资料: https://blog.csdn.net/nimasike/article/details/51457229 https://www.cnblogs.com/zhangqie/p/643 ...

  5. 【剑指offer】不使用新变量,交换两个变量的值,C++实现

    # 题目 不使用新变量,交换两个变量的值. # 思路 方法一:使用加减法操作,交换两个变量的值. A = A+B B = A-B A = A-B 方法二:使用异或运算,交换两个变量的值 A = A^B ...

  6. Docker部署IPython

    本文的部署环境是Ubuntu 14.04 Docker Docker 详细概念可以去search,简单来说就是把应用打包到一个容器里的轻量级系统虚拟化服务 IPython Notebook IPyth ...

  7. threejs Object的点击(鼠标)事件(获取点击事件的object)

    objects=[]; raycaster = new THREE.Raycaster(); mouse = new THREE.Vector2(); //监听全局点击事件,通过ray检测选中哪一个o ...

  8. BZOJ1087 SCOI2005 互不侵犯King 【状压DP】

    BZOJ1087 SCOI2005 互不侵犯King Description 在N×N的棋盘里面放K个国王,使他们互不攻击,共有多少种摆放方案.国王能攻击到它上下左右,以及左上左下右上右下八个方向上附 ...

  9. DependencyProperty.UnsetValue 的正确打开方式

    无论是 WPF,还是 UWP,只要你用了绑定或者标记扩展,一定会碰到一个神奇的值——DependencyProperty.UnsetValue.UnsetValue 是什么意思?为什么会出现这个值呢? ...

  10. waitKey()

    waitKey仅对窗口机制起作用,即namedWindow产生的窗口.若在此之前没有产生窗口,则waitKey相当于未执行. 注:namedWindow产生的窗口: namedWindow()+ims ...