Druid是一个开源的、分布式的、列存储系统,特别适用于大数据上的(准)实时分析统计。且具备较好的稳定性(Highly Available)。 其相对比较轻量级,文档很是完善,也比较容易上手。
Druid vs 其余系统
Druid vs Impala/Shark
Druid和Impala、Shark 的比较基本上能够归结为须要设计什么样的系统html
Druid被设计用于:node
- 一直在线的服务
- 获取实时数据
- 处理slice-n-dice式的即时查询
查询速度不一样:mysql
- Druid是列存储方式,数据通过压缩加入到索引结构中,压缩增长了RAM中的数据存储能力,可以使RAM适应更多的数据快速存取。索引结构意味着,当添加过滤器来查询,Druid少作一些处理,将会查询的更快。
- Impala/Shark能够认为是HDFS之上的后台程序缓存层。 可是他们没有超越缓存功能,真正的提升查询速度。
数据的获取不一样:算法
- Druid能够获取实时数据。
- Impala/Shark是基于HDFS或者其余后备存储,限制了数据获取的速度。
查询的形式不一样:sql
- Druid支持时间序列和groupby样式的查询,但不支持join。
- Impala/Shark支持SQL样式的查询。
Druid vs Elasticsearch
Elasticsearch(ES) 是基于Apache Lucene的搜索服务器。它提供了全文搜索的模式,并提供了访问原始事件级数据。 Elasticsearch还提供了分析和汇总支持。根据研究,ES在数据获取和汇集用的资源比在Druid高。json
Druid侧重于OLAP工做流程。Druid是高性能(快速汇集和获取)以较低的成本进行了优化,并支持普遍的分析操做。Druid提供告终构化的事件数据的一些基本的搜索支持。缓存
Segment: Druid中有个重要的数据单位叫segment,其是Druid经过bitmap indexing从raw data生成的(batch or realtime)。segment保证了查询的速度。能够本身设置每一个segment对应的数据粒度,这个应用中广告流量查询的最小粒度是天,因此天天的数据会被建立成一个segment。注意segment是不可修改的,若是须要修改,只可以修改raw data,从新建立segment了。服务器
架构

Druid自己包含5个组成部分:Broker nodes, Historical nodes, Realtime nodes, Coordinator Nodes和indexing services. 分别的做用以下:架构
- Broker nodes: 负责响应外部的查询请求,经过查询Zookeeper将请求划分红segments分别转发给Historical和Real-time nodes,最终合并并返回查询结果给外部;
- Historial nodes: 负责’Historical’ segments的存储和查询。其会从deep storage中load segments,并响应Broder nodes的请求。Historical nodes一般会在本机同步deep storage上的部分segments,因此即便deep storage不可访问了,Historical nodes仍是能serve其同步的segments的查询;
- Real-time nodes: 用于存储和查询热数据,会按期地将数据build成segments移到Historical nodes。通常会使用外部依赖kafka来提升realtime data ingestion的可用性。若是不须要实时ingest数据到cluter中,能够舍弃Real-time nodes,只定时地batch ingestion数据到deep storage;
- Coordinator nodes: 能够认为是Druid中的master,其经过Zookeeper管理Historical和Real-time nodes,且经过Mysql中的metadata管理Segments
- Druid中一般还会起一些indexing services用于数据导入,batch data和streaming data均可以经过给indexing services发请求来导入数据。
Druid还包含3个外部依赖分布式
- Mysql:存储Druid中的各类metadata(里面的数据都是Druid自身建立和插入的),包含3张表:”druid_config”(一般是空的), “druid_rules”(coordinator nodes使用的一些规则信息,好比哪一个segment从哪一个node去load)和“druid_segments”(存储每一个segment的metadata信息);
- Deep storage: 存储segments,Druid目前已经支持本地磁盘,NFS挂载磁盘,HDFS,S3等。Deep Storage的数据有2个来源,一个是batch Ingestion, 另外一个是real-time nodes;
- ZooKeeper: 被Druid用于管理当前cluster的状态,好比记录哪些segments从Real-time nodes移到了Historical nodes;
查询
Druid的查询是经过给Broker Nodes发送HTTP POST请求(也能够直接给Historical or Realtime Node),具体可见Druid官方文档。查询条件的描述是json文件,查询的response也是json格式。Druid的查询包含以下4种:
- Time Boundary Queries: 用于查询所有数据的时间跨度
- groupBy Queries: 是Druid的最典型查询方式,很是相似于Mysql的groupBy查询。query body中几个元素能够这么理解:
- “aggregation”: 对应mysql”select XX from”部分,即你想查哪些列的聚合结果;
- “dimensions”: 对应mysql”group by XX”,即你想基于哪些列作聚合;
- “filter”: 对应mysql”where XX”条件,即过滤条件;
- “granularity”: 数据聚合的粒度;
- Timeseries queries: 其统计知足filter条件的”rows”上某几列的聚合结果,相比”groupBy Queries”不指定基于哪几列进行聚合,效率更高;
- TopN queries: 用于查询某一列上按照某种metric排序的最多见的N个values;
本文小结
- Druid是一个开源的,分布式的,列存储的,适用于实时数据分析的系统,文档详细,易于上手;
- Druid在设计时充分考虑到了Highly Available,各类nodes挂掉都不会使得druid中止工做(可是状态会没法更新);
- Druid中的各个components之间耦合性低,若是不须要streaming data ingestion彻底能够忽略realtime node;
- Druid的数据单位Segment是不可修改的,咱们的作法是生成新的segments替换现有的;
- Druid使用Bitmap indexing加速column-store的查询速度,使用了一个叫作CONCISE的算法来对bitmap indexing进行压缩,使得生成的segments比原始文本文件小不少;
- 在咱们的应用场景下(一共10几台机器,数据大概100列,行数是亿级别),平均查询时间<2秒,是一样机器数目的Mysql cluter的1/100 ~ 1/10;
- Druid的一些“局限”:
- Segment的不可修改性简化了Druid的实现,可是若是你有修改数据的需求,必须从新建立segment,而bitmap indexing的过程是比较耗时的;
- Druid能接受的数据的格式相对简单,好比不能处理嵌套结构的数据