2019独角兽企业重金招聘Python工程师标准>>>
简介
Druid 是一个开源的,分布式的,列存储的,适用于实时数据分析的存储系统,能够快速聚合、灵活过滤、毫秒级查询、和低延迟数据导入。
Druid在设计时充分考虑到了高可用性,各种节点挂掉都不会使得druid停止工作(但是状态会无法更新);
Druid中的各个组成部分之间耦合性低,如果不需要实时数据完全可以忽略实时节点;
Druid使用Bitmap indexing加速列存储的查询速度,并使用CONCISE算法来对bitmap indexing进行压缩,使得生成的segments比原始文本文件小很多;
架构
整体架构
Druid集群包含不同类型的节点,而每种节点都被设计来做好某组事情。这样的设计可以隔离关注并简化整个系统的复杂度。
不同节点的运转几乎都是独立的并且和其他的节点有着最小化的交互,因此集群内的通信故障对于数据可用性的影响非常小。
Druid集群的构成和数据流向如图1所示:
(图1)
Druid 本身包含了五种节点 : Realtime、Historical、Coordinator、Broker、Indexer
Historical 历史节点是进行存储和查询的“历史”数据(非实时)的工作区,它会从深存储区(Deep Storage)中加载数据段(Data/Segments),响应 Broker 节点的查询请求并返回结果。历史节点通常会在本机同步深存储区上的部分数据段,所以即使深存储区不可访问了,历史节点还是能查询到已经同步的数据段。
Realtime 实时节点是进行存储和查询实时数据的工作区,它也会响应Broker节点的查询请求并返回结果 。实时节点会定期地将数据建立成数据段移到历史节点中。
Coordinator 协调节点可以认为是Druid中的master,它通过Zookeeper管理历史节点和实时节点,且通过Mysql中的metadata管理数据段。
Broker节点负责响应外部的查询请求,通过查询Zookeeper将请求分别转发给历史节点和实时节点,最终合并并返回查询结果给外部, 由Broker节点通过zookeeper决定哪些历史节点和实时节点提供服务。
Indexer 索引节点负责数据导入,加载批次和实时数据到系统中,并可以修改存储到系统中的数据 。
Druid 包含3个外部依赖 :Mysql、Deep storage、Zookeeper
Mysql:存储关于Druid中的metadata而不是存储实际数据,包含3张表:”druid_config”(通常是空的), “druid_rules”(协作节点使用的一些规则信息,比如哪个segment从哪个node去load)和“druid_segments”(存储每个segment的metadata信息);
Deep storage: 存储segments,Druid目前已经支持本地磁盘,NFS挂载磁盘,HDFS,S3等。Deep Storage的数据有2个来源,一个是批数据摄入, 另一个来自实时节点;
ZooKeeper: 被Druid用于管理当前cluster的状态,比如记录哪些segments从实时节点移到了历史节点;
实时节点
实时节点封装了导入和查询事件数据的功能,经由这些节点导入的事件数据可以立刻被查询。实时节点只关心一小段时间内的事件数据,并定期把这段时间内收集的这批数据导入到深存储区里。实时节点通过Zookeeper来宣布它们的在线状态和它们提供的数据。
如图2,实时节点缓存事件数据到内存中的索引上,然后有规律的持久化到磁盘上。在转移之前,持久化的索引会周期性地合并在一起。查询会同时命中内存中的和已持久化的索引。所有的实时节点都会周期性的启动后台的计划任务搜索本地的持久化索引,后台计划任务将这些持久化的索引合并到一起并生成一块不可变的数据,这些数据块包含了一段时间内的所有已经由实时节点导入的事件数据,称这些数据块为”Segment”。在传送阶段,实时节点将这些segment上传到一个永久持久化的备份存储中,通常是一个分布式文件系统,例如S3或者HDFS,称之为”Deep Storage”(深存储区)。
历史节点
历史节点遵循shared-nothing的架构,因此节点间没有单点问题。节点间是相互独立的并且提供的服务也是简单的,它们只需要知道如何加载、删除和处理Segment。类似于实时节点,历史节点在Zookeeper中通告它们的在线状态和为哪些数据提供服务。加载和删除segment的指令会通过Zookeeper来进行发布,指令会包含segment保存在deep storage的什么地方和怎么解压、处理这些segment的相关信息。
如图3,在历史节点从深存储区下载某一segment之前,它会先检查本地缓存信息中看segment是否已经存在于节点中,如果segment还不存在缓存中,历史节点会从深存储区下载segment到本地。这阶段处理完成,这个segment就会在Zookeeper中进行通告。此时,这个segment就可以被查询了,查询之前需要将segment加载到内存中。
协调节点
协调节点主要负责Segment的管理和在历史节点上的分布。协调节点告诉历史节点加载新数据、卸载过期数据、复制数据、和为了负载均衡移动数据。Druid为了维持稳定的视图,使用一个多版本的并发控制交换协议来管理不可变的segment。如果任何不可变的segment包含的数据已经被新的segment完全淘汰了,则过期的segment会从集群中卸载掉。协调节点会经历一个leader选举的过程,来决定由一个独立的节点来执行协调功能,其余的协调节点则作为冗余备份节点。
Broker节点
Broker节点是历史节点和实时节点的查询路由。Broker节点知道发布于Zookeeper中的segment的信息,Broker节点就可以将到来的查询请求路由到正确的历史节点或者是实时节点,Broker节点也会将历史节点和实时节点的局部结果进行合并,然后返回最终的合并后的结果给调用者。Broker节点包含一个支持LRU失效策略的缓存。
如图4,每次Broker节点接收到查询请求时,都会先将查询映射到一组segment中去。这一组确定的segment的结果可能已经存在于缓存中,而不需要重新计算。对于那些不存在于缓存的结果,Broker节点会将查询转发到正确的历史节点和实时节点中去,一旦历史节点返回结果,Broker节点会将这些结果缓存起来以供以后使用,这个过程如图6所示。实时数据永远不会被缓存,因此查询实时节点的数据的查询请求总是会被转发到实时节点上去。实时数据是不断变化的,因此缓存实时数据是不可靠的。
Indexer节点
索引服务是运行索引任务相关的高可用性,分布式的服务。索引服务创建(有时破坏)Druid的Segment。索引服务有一个类似主/从的架构。
索引服务是由三个主要部分组成:可以运行单个任务的peon组件,用于管理peon的中层管理组件,以及管理任务分配到中层管理组件的overlord组件。overlord组件和中层管理组件可以在同一节点上或跨多个节点上运行,而中层管理组件和peon组件总是相同的节点上运行。
ZooKeeper
Druid 使用ZooKeeper(ZK)管理当前集群状态,在ZK上发生的操作有:
1.协调节点的leader选举
2.历史和实时节点发布segment协议
3.协调节点和历史节点之间的segment Load/Drop协议
4.overlord的leader选举
5.索引服务任务管理
Druid vs 其他系统
Druid vs Impala/Shark
Druid和Impala、Shark 的比较基本上可以归结为需要设计什么样的系统
Druid被设计用于:
- 一直在线的服务
- 获取实时数据
- 处理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提供了结构化的事件数据的一些基本的搜索支持。
Druid vs Spark
Spark是围绕弹性分布式数据集( RDD )的概念,建立了一个集群计算框架,可以被看作是一个后台分析平台。 RDD启用数据复用保持中间结果存在内存中,给Spark提供快速计算的迭代算法。这对于某些工作流程,如机器学习,相同的操作可应用一遍又一遍,直到有结果后收敛尤其有益。Spark提供分析师与不同算法各种各样运行查询和分析大量数据的能力。
Druid重点是数据获取和提供查询数据的服务,如果建立一个web界面,用户可以随意查看数据。
引用
论文: Druid A Real-time Analytical Data Store
官方文档:http://druid.io/docs/0.8.1/design/index.html
Druid是一个开源的、分布式的、列存储系统,特别适用于大数据上的(准)实时分析统计。且具有较好的稳定性(Highly Available)。 其相对比较轻量级,文档非常完善,也比较容易上手。
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能接受的数据的格式相对简单,比如不能处理嵌套结构的数据
druid.io 海量实时OLAP数据仓库 (翻译+总结) (1)——分析框架如hive或者redshift(MPPDB)、ES等
介绍
我是NDPmedia公司的大数据OLAP的资深高级工程师, 专注于OLAP领域, 现将一个成熟的可靠的高性能的海量实时OLAP数据仓库介绍给大家: druid.io
NDPmedia在2014年3月就开始使用, 见链接: http://blog.csdn.net/chenyi8888/article/details/37594771
druid是个很新的平台, 2013年底才开源出来, 虽然出现的比较晚, 但druid发展很快, 中国有几个公司开始使用, 2015年druid将会是爆发的一年
最近druid 的华人作者Fangjin从Metamarkets离职, 专门从事druid研发和推广.
以下翻译自http://druid.io/docs/0.7.1.1/, 并添加了自己的注解
什么是Druid
Druid 是一个开源的,能在海量时序数据上 (万亿级别数据量, 1000 TB级别数据)上面提供实时分析查询的OLAP数据仓库,Druid提供了廉价的实时数据插入和任意数据探索的能力。
Druid的主要功能
为分析而生 - Druid是为了解决在OLAP工作流中进行探索分析而生的. 它提供了大量的filters, aggregators和 query 类型,并且提供了一个用户添加新功能的框架. 用户可以利用Druid的集群实现例如topN和直方图等功能。
(注: 传统数据库, 查询几千万的数据, 就会出问题, 查不出来)
(注: druid就是一个能力超强的数据库, 执行例如SQL: select aColumn, bColumn sum(cColumn) from tableName where aColumn like 'xxx' and bColumn = 5 group by aColumn, bColumn having sum(cColumn) > 5 order by aColumn.)
(注: druid对SQL支持有限,现在是实验版本。YeahMobi 重新开发适配了SQL, 屏蔽了下层平台, SQL 语句可以路由到这三个平台 druid, impala, hive)
高交互式 - Druid的低延时数据插入允许数据在生成之后的毫秒范围之内就可以被用户查询到。Druid通过读取和扫描需要的数据来优化查询的延时。
高可用性 - Druid可以被用来实现需要持续提供服务的SaaS应用。即使是在系统升级的过程中,你的数据仍然可以被查询。而且Druid 集群的扩容或者缩减不会带来数据的丢失。
(注: 已经在生产环境之中验证: 添加字段, 集群扩容, 集群缩减)
可扩展性 - 现有的Druid系统可以很轻松的处理每天数十亿条记录和TB级别的数据。Druid本身是被设计来解决PB级别数据的。
为什么要用Druid?
Druid的初衷是为了解决在使用Hadoop进行查询时所遇见的高延时问题来提高交互性查询。尤其是当你对数据进行汇总之后并在你汇总之后的数据 上面进行查询时效果更好。将你汇总之后的数据插入Druid,随着你的数据量在不断增长,你仍然可以对Druid的查询能力非常有信心。当前的Druid 安装实例已经可以很好的处理以每小时数TB实时递增的数据量。
(注: 在我们的实践中 druid 查询统计100亿数据, 在5秒内响应。 查询1个月的数据, 基本可以在毫秒内完成。 比hadoop的常用的T+1 Map Reduce 高效多了.
你可以在拥有Hadoop的同时创建一个Druid系统。Druid提供了以一种互动式切片、切块方式来访问数据的能力,它在查询的灵活性和存储格式直接寻找平衡从而来提供更好的查询速度。
如果想了解更多细节,请参考 White Paper 和Design 文档.
什么情况下需要Druid?
当你需要在大数据集上面进行快速的,交互式的查询时
当你需要进行特殊的数据分析,而不只是简单的键值对存储时
当你拥有大量的数据时 (每天新增数百亿的记录、每天新增数十TB的数据)
当你想要分析实时产生的数据时
当你需要一个24x7x365无时无刻不可用的数据存储时
架构概述
druid在一定程度上是受搜索框架的启发, 通过建立不变数据视图和使用便于filter和aggregation的高度优化的格式来提高性能. Druid 集群有一系列不同类型的节点组成, 每种节点将一小部分事情做到极致。
Druid vs…
Druid-vs-Impala-or-Shark
Druid-vs-Redshift
Druid-vs-Vertica
Druid-vs-Cassandra
Druid-vs-Hadoop
Druid-vs-Spark
Druid-vs-Elasticsearch
数据框架世界一直在巨大的混乱的变化之中, 这个网页希望帮助潜在的用户评估和确定druid适合用户解决遇到的问题。 如果有错误请通过邮件列表或者其他渠道反馈.
转自:http://www.cnblogs.com/lpthread/p/4519687.html
德鲁伊与SQL-on-Hadoop(Impala / Drill / Spark SQL / Presto)
SQL-on-Hadoop引擎为各种数据格式和数据存储提供了执行引擎,许多可以将计算下推到Druid,同时为Druid提供SQL接口。
为了直接比较技术以及何时只使用其中一种技术,事情基本上取决于您的产品要求以及系统的设计目标。
德鲁伊的目的是为了
- 永远在线服务
- 实时摄取数据
- 处理slice-n-dice风格的即席查询
SQL-on-Hadoop引擎通常会回避Map / Reduce,而是直接从HDFS或某些情况下的其他存储系统查询数据。其中一些引擎(包括Impala和Presto)可以与HDFS数据节点共存,并与它们协调以实现查询的数据位置。这是什么意思?我们可以从三个一般方面谈谈它
- 查询
- 数据摄取
- 查询灵活性
查询
德鲁伊细分市场以自定义列格式存储数据。细分作为查询的一部分直接扫描,每个德鲁伊服务器计算一组最终在Broker级别合并的结果。这意味着在服务器之间传输的数据是查询和结果,并且所有计算都在内部作为Druid服务器的一部分完成。
大多数SQL-on-Hadoop引擎负责底层存储层和存储格式的查询规划和执行。它们是即使没有运行查询也能保持运行的进程(从Hadoop MapReduce中消除JVM启动成本)。一些(Impala / Presto)SQL-on-Hadoop引擎具有可以在存储数据的地方运行的守护程序进程,从而几乎消除了网络传输成本。仍然存在与将数据从底层存储层拉入计算层相关联的一些延迟开销(例如,serde时间)。我们并不知道这对性能有多大影响。
数据摄取
德鲁伊的构建允许实时摄取数据。您可以在摄取后立即摄取数据并对其进行查询,事件在数据中反映的速度之间的延迟主要取决于将事件传递给Druid所需的时间。
SQL-on-Hadoop基于HDFS或其他后备存储中的数据,其数据提取率受后备存储可以提供数据的速率的限制。通常,后备存储是数据可以快速获取的最大瓶颈。
查询灵活性
德鲁伊的查询语言水平相当低,并且映射到德鲁伊内部的运作方式。尽管德鲁伊可以与Plywood等高级查询规划器结合使用,以支持大多数SQL查询和分析SQL查询(减去大型表之间的连接),但基础德鲁伊的灵活性不如SQL-on-Hadoop解决方案的通用处理。
SQL-on-Hadoop支持具有完全连接的SQL样式查询。
德鲁伊与Parquet
Parquet是一种列存储格式,旨在与SQL-on-Hadoop引擎配合使用。Parquet没有查询执行引擎,而是依靠外部源来从中提取数据。
德鲁伊的存储格式针对线性扫描进行了高度优化。尽管德鲁伊支持嵌套数据,但Parquet的存储格式更为分层,并且更适合二进制分块。从理论上讲,这应该会导致德鲁伊的扫描更快。
德鲁伊与键/值商店(HBase / Cassandra / OpenTSDB)
Druid针对扫描和聚合进行了高度优化,它支持任意深入钻取数据集。密钥/值存储中以两种方式支持相同的功能:
- 预先计算可能的用户查询的所有排列
- 范围扫描事件数据
预计算结果时,键是查询的确切参数,值是查询的结果。
查询返回非常快,但是以灵活性为代价,因为预先计算每个可能的查询排列都不可能进行临时探索查询。预先计算所有ad-hoc查询的所有排列导致结果集随着数据集的列数呈指数增长,并且对复杂的真实世界数据集的预计算查询可能需要数小时的预处理时间。
使用键/值存储进行聚合的另一种方法是使用事件的维度作为键,事件测量值作为值。通过对此数据发出范围扫描来完成聚合。特定于时间序列的数据库(如OpenTSDB)使用此方法。这里的一个限制是键/值存储模型没有除了前缀范围之外的任何类型的过滤的索引,可以用于将查询过滤到度量和时间范围,但无法解析复杂谓词以缩小要扫描的确切数据。当要扫描的行数变大时,此限制可能会大大降低性能。使用键/值存储实现良好的局部性也更难,因为大多数不支持将聚合下推到存储层。
对于任意数据探索(灵活的数据过滤),德鲁伊的自定义列格式无需预先计算即可实现即席查询。该格式还支持对列进行快速扫描,这对于良好的聚合性能非常重要