druid介绍(一)

目录

什么是druid

druid使用场景

Druid架构

datasources和segments

查询处理流程

外部依赖

深度存储

元数据存储

ZooKeeper



什么是druid

druid设计之处的目的是为了在大数据集上进行高效的slice-and-dice分析(类似OLAP)。druid经常会被用来作为强大可视化分析的存储模块,或者为高速的并发api提供支持。它的典型应用场景包括:

  • 用户点击分析
  • 网络流量分析
  • 服务器度量存储
  • 应用的性能度量
  • 数字市场分析
  • BI/OLAP

Druid的主要特色

  • 列式存储 
  • 分布式存储
  • 多并发处理
  • 支持实时/批量数据导入
  • 自我治愈、自我管理、易操作
  • 支持原生云,较好的若错功能不易丢失数据
  • 近似算法
  • 在导入数据的时候同时进行汇总计算

druid使用场景

druid的主要使用场景如下:

  • 插入频率很高,更新频率不高
  • 大部分的查询是面向聚合操作或者报表需求的
  • 数据是具有时间属性的
  • 系统可能有多个表,但是每次查询主要是对一个大分布式的表进行查询
  • 有的列具有非常多的数据,需要对它们进行快速统计或排序
  • 你希望从kafka、hdfs或面向对象存储诸如s3等

druid不适用的场景包括:

  • 希望快速的更新数据,druid支持流式数据的插入,但不支持更新
  • 你在创建离线报表,对数据的实时性要求不高
  • 你希望做很多的关联

 

Druid架构

       druid是面向多进程、分布式的架构,它的设计是面向云服务而且是易操作的。每个druid进程都是单独进行配置的,这使得集群具有非常灵活的特性。这种设计使得系统具有很好的容错性,即使一个节点发生宕机也不会影响其他节点。

druid的进程主要有:

  • Historical   这种重负荷进程负责处理“historical”数据的存储和查询(包括将要提交的流式数据)。这类进程会从深度存储中下载segment并且进行响应,需要注意的是它不支持写入功能。
  • MiddleManager    这种进程负责将数据写入集群,它们负责从外部接收数据并且写入druid新的segment中。
  • Broker    这种进程会接收外部客户端的查询并且将请求转发至Historical和MiddleManager节点,等待它们返回之后,Broker会将结果合并并且向客户端进行响应。
  • Coordinator    这种进程负责监护Historical进程,它们负责分配segment以保证各Historical能够均衡地进行处理数据。
  • Overload    这种进程是druid数据加载的核心控制器,它负责监护MiddleManager。Overload会将数据加载任务分配给MiddleManager,并且协助分发segment。
  • Router    它负责对Broker、Coordinator和Overload进行路由解析,应用客户端也可以直接和Broker、Coordinator与Overload进行交互,所以它是可选的。

Druid的各种进程可以分开部署,也可以一起部署,其中一种通用的部署方式是:

  • “Data”服务器负责运行Historical和MiddleManager进程
  • “Query”服务器负责运行Broker和Router(可选的)进程
  • “Master”服务器上跑Coordinator进程和Overload进程

除了上面描述的这些进程之外,Druid也需要三种外部的依赖。它们会使得整个架构更加合理,描述如下:

  • Deep Storage    这是一种共享的文件存储,主要是一些分布式对象存储诸如s3或hdfs,也可能是网络文件系统。
  • Metadata store    共享的元数据存储,主要是一些传统关系型数据库如PostgreSql或者Mysql
  • Zookeeper    用于内部服务寻址,协调和主节点的选举等

Druid的架构之所以这样设计,是因为它会使得druid集群更加容易操作。譬如将深度存储和元数据存储同集群其他节点分开,这将使得集群具有较好的容错功能,即使druid集群的所有服务器都挂了,你依然可以使用深度存储和元数据存储将集群进行启动。

下图描述了整个druid架构的查询和数据流程

druid介绍(一)_第1张图片

datasources和segments

Druid的数据存储在“datasources”中,这些和传统的RDBMS数据表非常类似。每个datasource都通过时间或者其他属性进行分区。每个时间段范围的数据称为“chunk”。在一个chunk中,数据又会分区为若干segments,每个segment都是一个单独的文件,通常情况下是由几百万条数据组成。我们知道segment是位于time chunk中的,我们可以理解为时间线上的数据,如下:

druid介绍(一)_第2张图片

每个数据源可能只由几个segment,也可能会有数百万的segment组成。 每个segment最初是由MiddleManager创建,这个时候它是可变的,并且还没有提交到深度存储当中。segment处理进程通过以下步骤来生成一个压缩过且支持快查的文件:

  • 列式存储
  • 适用位图技术进行索引
  • 使用若干算法进行压缩

这些算法包括:

  • 针对字符串列使用字典编码进行最小化存储
  • 位图压缩技术
  • 所有列的类型感知压缩

       segment块会定时地被提交和推送至深度存储当中。一旦存入,这些数据就不可更改,其控制权也由MiddleManager转移到Historical进程。同时,一条关于segment的记录也会被存储到metadata 存储中。这条记录是关于segment自我描述块,这些数据包括segment的结构,大小和它在深度存储中的位置。这些记录可以帮助Coordinator知道集群中数据的位置。

查询处理流程

       查询请求会首先进入到Broker,broker会识别哪些segment可能和这次请求有关。segment列表通常都是通过时间或者其他属性进行过滤。broker会识别出哪些Historical和MiddleManager在提供相关的segment,之后它会将请求发送给这些进程进行处理。Historical和Middlemanager会处理请求,之后返回结果。Broker会接收数据,并将它们进行汇总并且最终返回给最初的调用者。

       Broker筛选功能是非常重要的,它会帮助识别需要扫描哪些数据,但又不仅仅如此。为了进行更细粒度的筛选,每个segment中的索引结构帮助druid识别哪些行和查询的请求有关。一旦Druid识别出有用的行,它就仅仅存取和该请求有关的特定列。在这些列中,druid可以跳跃无用的行去找到有用的数据。

        总结以下,druid通过三种技术来提升效率:

  • 筛选有用的segment
  • 在segment中,使用索引去确定哪些行必须读取
  • 在segment中,仅仅读取相关的行和列

外部依赖

深度存储

Druid使用深度存储只是作为数据的备份,或者是作为在后端进程之间传输数据的方式。为了响应一次查询,Historical进程不会从深度存储中获取数据,而是从存储在本地磁盘中预处理过的segment。这意味着Druid从来也不需要在查询的时候从深度存储中存取数据,着可以极大地降低延迟。这也意味着无论对于深度存储,或者是Historical节点的数据你必须又足够的磁盘空间。

元数据存储

元数据存储系统中容纳了各种元数据,比如segment有效性信息、任务信息等。

ZooKeeper

Druid使用Zookeeper来管理当前集群的状态。

你可能感兴趣的:(druid)