Druid是一个开源的、分布式的、列存储系统,特别适用于大数据上的(准)实时分析统计。且具有较好的稳定性(Highly Available)。 其相对比较轻量级,文档非常完善,也比较容易上手。

Druid vs 其他系统

Druid vs Impala/Shark

Druid和Impala、Shark 的比较基本上可以归结为需要设计什么样的系统

Druid被设计用于:

  1. 一直在线的服务
  2. 获取实时数据
  3. 处理slice-n-dice式的即时查询

查询速度不同:

  • Druid是列存储方式,数据经过压缩加入到索引结构中,压缩增加了RAM中的数据存储能力,能够使RAM适应更多的数据快速存取。索引结构意味着,当添加过滤器来查询,Druid少做一些处理,将会查询的更快。
  • Impala/Shark可以认为是HDFS之上的后台程序缓存层。 但是他们没有超越缓存功能,真正的提高查询速度。

数据的获取不同:

  • Druid可以获取实时数据。
  • Impala/Shark是基于HDFS或者其他后备存储,限制了数据获取的速度。

查询的形式不同:

  • Druid支持时间序列和groupby样式的查询,但不支持join。
  • Impala/Shark支持SQL样式的查询。

Druid vs Elasticsearch

Elasticsearch(ES) 是基于Apache Lucene的搜索服务器。它提供了全文搜索的模式,并提供了访问原始事件级数据。 Elasticsearch还提供了分析和汇总支持。根据研究,ES在数据获取和聚集用的资源比在Druid高。

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;

本文小结

  1. 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比原始文本文件小很多;
  2. 在我们的应用场景下(一共10几台机器,数据大概100列,行数是亿级别),平均查询时间<2秒,是同样机器数目的Mysql cluter的1/100 ~ 1/10;
  3. Druid的一些“局限”:
    • Segment的不可修改性简化了Druid的实现,但是如果你有修改数据的需求,必须重新创建segment,而bitmap indexing的过程是比较耗时的;
    • Druid能接受的数据的格式相对简单,比如不能处理嵌套结构的数据

Druid(准)实时分析统计数据库——列存储+高效压缩的更多相关文章

  1. Vertica: 基于DBMS架构的列存储数据仓库

    介绍 Vertica(属于HP公司),是一个基于DBMS架构的数据库系统,适合读密集的分析型数据库应用,比方数据仓库,白皮书中全名称为VerticaAnalytic Database.从命名中也可以看 ...

  2. SQL Server 2014 聚集列存储

    SQL Server 自2012以来引入了列存储的概念,至今2016对列存储的支持已经是非常友好了.由于我这边线上环境主要是2014,所以本文是以2014为基础的SQL Server 的列存储的介绍. ...

  3. SQL Server 列存储索引概述

    第一次接触ColumnStore是在2017年,数据库环境是SQL Server 2012,Microsoft开始在SQL Server 2012中推广列存储索引,到现在的SQL Server 201 ...

  4. 在 Kubernetes 上快速测试 Citus 分布式 PostgreSQL 集群(分布式表,共置,引用表,列存储)

    准备工作 这里假设,你已经在 k8s 上部署好了基于 Citus 扩展的分布式 PostgreSQL 集群. 查看 Citus 集群(kubectl get po -n citus),1 个 Coor ...

  5. 腾讯Hermes设计概要——数据分析用的是列存储,词典文件前缀压缩,倒排文件递增id、变长压缩、依然是跳表-本质是lucene啊

    转自:http://data.qq.com/article?id=817 三.Hermes设计概要 架构描述 系统核心进程均采用分散化设计,根据业务发展需求,可随意扩缩容机器; 周期性数据直接通过td ...

  6. Apache Druid 底层存储设计(列存储与全文检索)

    导读:首先你将通过这篇文章了解到 Apache Druid 底层的数据存储方式.其次将知道为什么 Apache Druid 兼具数据仓库,全文检索和时间序列的特点.最后将学习到一种优雅的底层数据文件结 ...

  7. lucene底层数据结构——FST,针对field使用列存储,delta encode压缩doc ids数组,LZ4压缩算法

    参考: http://www.slideshare.net/lucenerevolution/what-is-inaluceneagrandfinal http://www.slideshare.ne ...

  8. Hadoop_常用存储与压缩格式

    HDFS文件格式 file_format: TEXTFILE 默认格式 RCFILE hive 0.6.0 和以后的版本 ORC hive 0.11.0 和以后的版本 PARQUET hive 0.1 ...

  9. SQL Server 列存储索引强化

    SQL Server 列存储索引强化 SQL Server 列存储索引强化 1. 概述 2.背景 2.1 索引存储 2.2 缓存和I/O 2.3 Batch处理方式 3 聚集索引 3.1 提高索引创建 ...

随机推荐

  1. 《zw版·Halcon-delphi系列原创教程》 Halcon分类函数012,polygon,多边形

    <zw版·Halcon-delphi系列原创教程> Halcon分类函数012,polygon,多边形 为方便阅读,在不影响说明的前提下,笔者对函数进行了简化: :: 用符号“**”,替换 ...

  2. 【转】PowerShell入门(五):Cmd命令与PowerShell命令的交互

    转至:http://www.cnblogs.com/ceachy/archive/2013/02/18/Call_Between_Cmd_And_PowerShell.html 单独使用一种脚本来完成 ...

  3. 【request_firmware】 linux内核下载模块固件接口【转】

    转自:http://blog.csdn.net/magod/article/details/6049558 [-] 8 处理固件 1481 内核固件接口 1482 它如何工作 14.8. 处理固件 作 ...

  4. python脚本利用windows计划定时执行

  5. 第一册解说and表现

    综合日语第一册第五单元到十五单元的解说表现大集会:(这么一来一本书都被我搬上来啦--) 第五课 1.始めました: 初次见面时的寒暄用语,表示“初次见面(请多多观照)”之意. 2.どうぞよろしく: 用于 ...

  6. Java 新手学习 CSS样式列表 排版 格式布局

    1,样式表分为  内联样式表   内嵌样式表  外部样式表  三种. 内联样式表是直接写在标签里面的  比如 <p style=“”></p>  <div style=& ...

  7. Unity3D Function Not Supported - Unity动画事件提示不支持的解决方法

    把脚本放在所有组件的最上面 然后刷新一下就好了 如果还是显示不支持就是参数问题.比如不支持bool参数,但支持string参数. 所以最好用无参数的

  8. KVM虚拟机virsh常用参数

    线上虚拟机挂了,常用的命令忘了,记录下 链接:http://www.ibm.com/support/knowledgecenter/zh/linuxonibm/liabp/liabpcommonvir ...

  9. Reflection

    Reflection 反射能在运行时获取一个类的全部信息,并且可以调用类方法,修改类属性,创建类实例. 而在编译期间不用关心对象是谁 反射可用在动态代理,注解解释,和反射工厂等地方. -------- ...

  10. Mysql新知识点150928

    1.select distinct(DATE_FORMAT(updatetime,'%Y-%m')) as updatetime from barcode where pid!=0 order by ...