背景
找了好久的大数据实时平台,还能面向OLAP分析场景的,仔细罗列了一下,Elasticsearch、Kylin、Druid, 当然还有比较冷门的ClickHouse等等。线上可以使用的无外乎这些主流选择。
- Elasticsearch支持实时检索聚合,数据实时elt可以通过ingest Node来完成。但其Query语法门槛较高;
- Kylin目前可以支持流式创建cube,但build过程很长,一旦cube完成,查询速度很快,但查询模式偏固定;
介绍
Druid在大数据领域已经很久了, 只听其声未见其人,所以今天我就来讲讲Druid到底是个啥?
简单来说,Druid是一个分布式的、支持实时多维OLAP分析的数据处理系统。它既支持高速的 数据实时摄入处理 ,也支持 实时且灵活的多维数据分析查询 。因此Druid最常用的场景就是大数据背景下、灵活快速的多维OLAP分析。 另外,Druid还有一个关键的特点:它支持根据时间戳对数据进行预聚合摄入和聚合分析,因此也有用户经常在有 时序 数据处理分析的场景中用到它。
- 需要交互式聚合和快速探究大量数据时;
- 需要实时查询分析时;
- 具有大量数据时,如每天数亿事件的新增、每天数10T数据的增加;
- 对数据尤其是大数据进行实时分析时;
- 需要一个高可用、高容错、高性能数据库时。
先扯皮开源界的命名问题,经常撞车,导致码农老鼠老虎傻傻分不清。但不撞车的话,又显得名字太过冷僻,没法朗朗上口。 在这里,阿里巴巴也曾创建过一个开源项目叫作Druid,但它是一个数据库连接池的项目。和本文讨论的Druid没有任何关系,它们解决完全不同的问题。
目前大数据的轮子这么多,但没有一个轮子是万金油项目(手动狗头)。技术选型的时候一定要确定自己的需求,才能有的放矢。本文主要就“海量数据下的实时多维OLAP分析”为背景介绍Druid。
存储格式
Druid自己有着数据存储的逻辑和格式(主要是DataSource和Segment),而其整个框架也是围绕着数据存储展开的。
DataSource
DataSource对应关系数据库中的Table概念。 一个DataSource主要包括三种元素:
- 时间列(TimeStamp), 表明每行数据的时间值,默认使用 UTC 时间格式且精确到毫秒级别。这个列是数据聚合与范围查询的重要维度。
- 维度列(Dimension): 维度来自于OLAP的概念,用来标识数据行的各个类别信息。
- 指标列(Metric): 指标对应于OLAP概念中的Fact,是用于聚合和计算的列这些指标列通常是一些数字,计算操作通常包括 Count、Sum 和 Mean 等。
无论是实时处理还是批处理,Druid都会对选择的指标列进行Roll Up操作。这种操作,使得Druid不仅能节省存储空间,提高处理速度,同时还能加送聚合查询的效率。
Segment
如果说DataSource是一个逻辑概念,Segment就是数据的实际物理存储格式,Druid 正是通过 Segment 实现了对数据的横纵向切割(Slice and Dice)操作。从数据按时间分布的角度来看, 通过参数 segmentGranularity 的设置,Druid 将不同时间范围内的数据存储在不同的 Segment 数据块中,这便是所谓的数据横向切割。这种设计为 Druid 带来一个显而易见的优点:按时间范围查询数据时,仅需要访问对应时间段内的这些 Segment 数据块,而不需要进行全表数据范围查询,这使效率得到了极大的提高。
对比hive中的partition概念,一个parition一个目录, 而Druid里面是一个窗口一个Segment。
同时,在 Segment 中也面向列进行数据压缩存储,这便是所谓的数据纵向切割。而且对Segment 中的维度列使用了 Bitmap 技术对其数据的访问进行了优化。其中,Druid会为每一维度列存储所有列值、创建字典(用来存储所有列值对应的ID)以及为每一个列值创建其bitmap索引以帮助快速定位哪些行拥有该列值。
总体来说,数据的存储方式都是RC格式的扩展。
实时节点架构
Druid架构包含四种节点:
- 实时节点(RealtimeNode): 即时摄入实时数据,以及生成Segment数据文件。
- 历史节点(HistoricalNode): 加载已生成好的数据文件,以供数据查询。
- 查询节点(Broker Node): 对外提供数据查询服务,并同时从实时节点与历史节点查询数据,合并后返回给调用方。
- 协调节点(CoordinatorNode): 负责历史节点的数据负载均衡,以及通过规则(Rule) 管理数据的生命周期。
同时集群还依赖三种外部服务:
- 元数据库(Metastore): 存储Druid集群的原数据信息,比如Segment的相关信息,一般用 MySQL 或 PostgreSQL。
- 分布式协调服务(Coordination): 为Druid集群提供一致性协调服务的组件,通常为Zookeeper。
- 数据文件存储库(DeepStorage): 存放生成的Segment数据文件,并供历史节点下载 对于单节点集群可以是本地磁盘,而对于分布式集群一般是 HDFS 或 NFS。

从数据流转的角度来看,实时/批量数据从架构图的左侧进入系统,实时流数据会被实时节点消费,然后实时节点将生成的 Segment 数据文件上传到数据文件存储库;而批量数据经过 Druid 集群消费后会被直接上传到数据文件存储库。同时,查询节点会响应外部的查询请求,并将分别从实时节点与历史节点查询到的结果合并后返回,典型的lamda架构。