Druid翻译零:概念

Druid是一个专门针对事件数据的OLAP查询而设计的开源数据存储系统。此页面旨在为读者介绍关于Druid存储数据的高级概述,以及Druid集群的架构。

数据

我们从一个在线广告的示例数据集开始讨论:

timestamp             publisher          advertiser  gender  country  click  price
2011-01-01T01:01:35Z  bieberfever.com    google.com  Male    USA      0      0.65
2011-01-01T01:03:63Z  bieberfever.com    google.com  Male    USA      0      0.62
2011-01-01T01:04:51Z  bieberfever.com    google.com  Male    USA      1      0.45
2011-01-01T01:00:00Z  ultratrimfast.com  google.com  Female  UK       0      0.87
2011-01-01T02:00:00Z  ultratrimfast.com  google.com  Female  UK       0      0.99
2011-01-01T02:00:00Z  ultratrimfast.com  google.com  Female  UK       1      1.53

熟悉OLAP的同学应该对这些概念肯定不会陌生,Druid也把数据集分为三个部分:

  • Timestamp column(时间字段):将时间字段单独处理,是因为Druid的所有查询都是围绕时间轴进行的。
  • Dimension columns(维度字段): 维度字段是数据的属性,一般被用来做数据的过滤。在示例数据集中有四个维度:publisher、advertiser、gender和 country。它们各自代表了我们用来分割数据的轴。
  • Metric columns(度量字段):度量字段是用来做数据的聚合计算的。在示例中, click和price是俩个度量。度量是可以衡量的数据,一般可以做count、sum等操作。在OLAP术语中也叫measures。

Roll-up

在海量数据处理中,一般对于单条的细分数据并不感兴趣,因为存在数万亿计这样的事件。然而这类数据的统计汇总是很有用的,Druid通过roll-up过程的处理,使数据在摄取加载阶段就做了汇总处理。Roll-up(汇总)是在维度过滤之前就做的第一级聚合操作。相等于如下伪代码:

GROUP BY timestamp, publisher, advertiser, gender, country
  :: impressions = COUNT(1),  clicks = SUM(click),  revenue = SUM(price)

原始数据压缩聚合之后就是这个样子:

 timestamp             publisher          advertiser  gender country impressions clicks revenue
 2011-01-01T01:00:00Z  ultratrimfast.com  google.com  Male   USA     1800        25     15.70
 2011-01-01T01:00:00Z  bieberfever.com    google.com  Male   USA     2912        42     29.18
 2011-01-01T02:00:00Z  ultratrimfast.com  google.com  Male   UK      1953        17     17.31
 2011-01-01T02:00:00Z  bieberfever.com    google.com  Male   UK      3194        170    34.01

可以看到,通过roll-up汇总数据后可以大大减少需要存储的数据量(高达100倍)。Druid在接收数据的时候汇总数据,以最小化需要存储的原始数据量。但是这种存储减少是有代价的,当我们roll up数据后,就没办法再查询详细数据了。换句话说roll-up后的粒度就是你能够探索数据的最小粒度,事件被分配到这个粒度。因此,Druid摄取规范将此粒度定义为数据的queryGranularity, 支持的最低queryGranularity是毫秒。

Sharding the Data

Druid的数据分片称为 segments,druid总是最先通过时间来分片,上面例子中我们聚合后的数据,可以按小时分为俩分片:
Segment sampleData_2011-01-01T01:00:00:00Z_2011-01-01T02:00:00:00Z_v1_0包含

 2011-01-01T01:00:00Z  ultratrimfast.com  google.com  Male   USA     1800        25     15.70
 2011-01-01T01:00:00Z  bieberfever.com    google.com  Male   USA     2912        42     29.18

Segment sampleData_2011-01-01T02:00:00:00Z_2011-01-01T03:00:00:00Z_v1_0包含

 2011-01-01T02:00:00Z  ultratrimfast.com  google.com  Male   UK      1953        17     17.31
 2011-01-01T02:00:00Z  bieberfever.com    google.com  Male   UK      3194        170    34.01

segments是一个包含数据的独立容器,内部数据以时间分割。segments为聚合的列做索引,数据依赖索引,按列方式存储。 所以druid得查询就转为了如何扫描segments了。
segment 由datasource(数据源)、interval(间隔)、version(版本号)和一个可选的分区号唯一的确定。 例如上面例子中,我们的segment的名字就是这种格式dataSource_interval_version_partitionNumber。

Indexing the Data

Druid能够取得这样的查询速度,主要取决于数据的存储方式。借鉴google等搜索引擎的思路,Druid生成不可变的数据快照,存储在针对分析查询高度优化的数据结构中。
Druid是列式存储也就意味着每一个列都是单独存储的。Druid查询时只会使用到与查询相关的列,而且Druid很好的支持了在查询时只扫描其需要的。不同的列可以采用不同的压缩方法,也能够建立与它们相关的不同索引。
Druid在每一个分片级别(segment)建立索引。

Loading the Data

Druid有实时和批量两种方式进行数据摄取。Druid中实时数据摄取方式是尽力而为。Druid暂时实时摄取暂时无法支持正好一次(Exactly once),当然在后续版本计划中会尽量去支持。通过批量创建能够准确映射到摄取数据的段,批量摄取提供了正好一次的保证。使用Druid的通用方式是用实时管道获取实时数据,用批量管道处理副本数据。

Querying the Data

Druid的本地查询语言是JSON通过HTTP,虽然社区在众多的语言中提供了查询库,包括SQL查询贡献库。
Druid设计用于单表操作,目前不支持join操作。因为加载到Druid中的数据需要规范化,许多产品准备在数据ETL(Extract-Transform-Load)阶段进行join。

The Druid Cluster

Druid集群是由不同类型节点组成的,每个节点各司其职:

  • Historical Nodes 历史节点通常构成Druid集群的骨干,历史节点在本地下载不可变的段,并对这些段进行查询。这些节点有一个无共享的体系结构,并知道如何加载数据段、丢弃数据段,并对数据段进行查询。
  • Broker Nodes Broker节点是客户端和应用从Druid查询获取数据的地方。Broker节点负责分配查询并且收集和合并结果,Broker节点知道哪些段放在哪里。
  • Coordinator Nodes Coordinator节点负责管理集群中历史节点的段,协调器节点告诉历史节点加载新的段、删除旧的段并且移动段来达到负载均衡。
  • Real-time Processing Druid中的实时处理可以使用独立的实时节点或使用索引服务来完成。实时逻辑在这两个服务之间是共同的。实时处理包括接收数据、索引数据(创建数据段)和将数据段传输到历史节点。通过实时处理逻辑接收数据,数据就是可查询的。切换过程也是无损的,数据在整个过程中保持可查询。

外部依赖

Druid对集群操作有几个外部依赖关系。

  • Zookeeper Druid依赖zookeeper进行集群内部通信。
  • Metadata Storage Druid依赖元数据存储来存储段和配置的元数据。创建段的服务向元数据存储写入新条目,并且协调器节点监视元数据存储以知道何时需要加载新数据或需要丢弃旧数据。元数据存储不包含在查询路径中。MySQL和PostgreSQL是生产系统中常用的元数据存储数据库。当在单机系统上运行所有Druid节点,可以使用Derby 数据库。
  • Deep Storage 深度存储用作段的永久备份。创建段的服务将段上传到深度存储,历史节点从深度节点上下载段。深度存储也不包含在查询路径里。S3和HDFS是流行的深度存储方式。

高可用性

Druid设计避免了单点故障。不同类型的节点故障并不会影响其他类型节点的服务。为了运行高可用的Druid集群,需要每个节点类型至少2个节点。

全面架构

Druid论文

原文链接:http://druid.io/docs/0.9.2/design/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,242评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,769评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,484评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,133评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,007评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,080评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,496评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,190评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,464评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,549评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,330评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,205评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,567评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,889评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,160评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,475评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,650评论 2 335

推荐阅读更多精彩内容