܄

海量数据,快速聚合:去哪儿大住宿如何玩转Druid

【数据猿导读】 长期以来,Qunar 大住宿的数据仓库主要使用 Hive 作为主要的查询引擎,部分需求配合 Postgres 和 Mysql 数据库,用作报表的汇总和展示。随着业务的发展,数据量和常用的维度都在快速的增长,以订单为例,目前常用的维度超过50个,采用关系型数据库存储,很难保证查询汇总的性能...

海量数据,快速聚合:去哪儿大住宿如何玩转Druid

Why Druid

长期以来,Qunar 大住宿的数据仓库主要使用 Hive 作为主要的查询引擎,部分需求配合 Postgres 和 Mysql 数据库,用作报表的汇总和展示。随着业务的发展,数据量和常用的维度都在快速的增长,以订单为例,目前常用的维度超过50个,采用关系型数据库存储,很难保证查询汇总的性能。急需一个适用于分析汇总查询的 OLAP 引擎。

Druid 是一个开源的,分布式的,列存储的,适用于实时数据分析的存储系统,能够快速聚合、灵活过滤、毫秒级查询、和低延迟数据导入。目前最新版本是0.9.1.1,在 Apache License 2.0协议下开源。其设计的适用场景,就是对 PB 级数据的快速聚合查询。

Druid 架构

为了做到毫秒级的查询相应,Druid的核心思想是对数据的索引和预汇总。Druid 集群采用了 share nothing 的架构。一个 Druid 集群由5组不同角色的节点组成:

Realtime

Indexer

Broker

Historical

Coordinator

同时依赖3个外部服务:

Zookeeper

MetadataStore (一个关系型数据库)

Deep Storage (HDFS,本地文件系统,S3)

每组节点在集群中有不同的作用:

Coordinator 节点负责统一分配管理

Historical 节点保存的

segment Realtime 节点接收实时数据,并进行实时汇总 

Indexer 节点负责处理批量索引请求,管理批量索引任务

Broker 节点负责处理客户端提交的查询

Historical 节点是 Druid 集群的主力,负责缓存和查询索引好的数据,生成部分聚合结果,并将结果交给 Broker 节点做进一步聚合。

数据在不同节点间的流向:

Realtime 节点接受实时数据,对数据进行实时聚合,并定期将已经完成的 Segment 推向 Historical 节点

Indexer 节点接受批量导入请求,管理批量索引任务,并将生成的 segment 交给 Historical 节点

客户端的查询提交到 Broker 节点,然后根据 Coordinator 的信息,将查询拆分到不同的 Historical 节点和 Realtime 节点,再将得到的结果聚合返回给客户端。

Druid 如何索引数据

Druid 不保存明细数据,由 Druid 索引好的数据本身已经是部分聚合后的结构,可以进一步合并后得到最终的结果。

Druid 将数据拆分为了三段:时间戳,维度和指标。

在上面的数据中,order_time 是时间戳,用于将数据切分成不同的 segment;hotel_seq,city 是维度,Druid 会对每一列存储下面三组不同的信息:

1.枚举字典

定义:对维度中的所有可能值进行编码,以最小化存储空间使用 以 city 一列为例,Druid 会保存类似下面的字典信息: { “beijing”: 0, “shanghai”:1 }

2. 列存储

定义:经过编码的列存储。以 city 一列为例,最终会保存 [0, 0, 1, 0]这样的信息

3. 倒排 bitmap 索引

定义:每个枚举值,出现在数据中的哪些行中。用于快速检索。本质是一个巨大的稀疏矩阵。实际存储中一般的文本压缩就有非常好的压缩效果。以city一列为例,会存储 { “beijing”: [1, 1, 0, 1], “shanghai”: [0, 0, 1, 0] } 这样的索引。

这种存储结构是的可以保证快速的检索枚不同举值对应的部分聚合结果,并且每种索引都有非常高效的压缩存储算法。

业务使用场景

目前,我们主要使用 Druid 解决对订单实时的多维度分析的应用场景。不同于其他的数据,例如流量等,订单的业务场景很复杂,很多维度值和指标项随着订单处理流程,或者用户的主动变更,会发生变化。为了应对这种场景,目前我们采用了实时和离线结合的方式处理订单数据:

1、实时部分会接收业务线订单创建的相应的消息,抽取订单相应的维度,并且计算部分关键指标信息,通过 kafka 实时推到 Druid 集群;

2、离线部分会根据每天的离线数据仓库每日计算的准确结果,重新索引,替换掉三个月内的数据。

再实际的使用中,我们发现这个方案有下面几个问题:

1、Druid 没有保存明细数据,部分运营场景需要筛选订单明细,Druid 无法支持;

2、Druid 查询使用自己的 DSL,类似 ES。手工书写查询比较困难。

Caravel 可以比较好的解决这两个问题。

Caravel

Caravel 是由 Airbnb 开发的数据可视化平台,提供 Druid 和 Python DBAPI 支持的关系型数据库,包括 Mysql、Postgres、Presto、Kylin 等。提供简单直观的配置界面,配置一个漂亮的 Dashboard 非常简单。

针对 Druid 使用中遇到的问题都提供了比较完善的解决方案:

1、查询不好写 -> Caravel 可以通过拖拽和选择配置报表

2、明细数据无法导出 -> Caravel 同时支持 Presto 和 Druid,通过改造 Caravel 使其支持明细数据走 Presto 查询,汇总走 Druid‘ 

总结

Druid 有下面的优缺点:

Pros:

高可用,水平扩展。靠堆硬件就能解决性能问题;

高效和压缩和索引算法,能做到 PB 级数据量下的过滤汇总10 ms 以下的相应时间;

实时导入和批量索引结合;

schema 灵活。同一个 datasource 下的不同 segment 可以有不同的指标与维度。

Cons:

数据经过初步聚合索引,无法看到明细数据;

无法更新已导入的数据。更新需要重新索引整个 segment;

维度和指标需要预先定义好,添加新指标需要重新索引,才能对历史数据生效。

经常有人将 Druid 和其他的 OLAP 引擎比较,和常见的可以用作 OLAP 的引擎比较:

对比ES:

ES 偏向于文本检索。虽然ES目前支持聚合查询,但是聚合操作占用的资源非常高。

Druid 更适合聚合分析。

对比 Spark/Hive/Impala/Presto 等查询引擎:

这些查询引擎重点是更灵活的查询方式和完整的SQL支持。

Druid 专注于对热点数据的探索分析。

对比 Kylin:

在 Kylin 的开发者邮件组里,对这两个引擎做过非常深入的比较,主要有下面几点:

Kylin 更适合复杂的 OLAP 场景,Druid 适合试试分析场景;

Druid 能实时从 kafka 拉取数据,Kylin 的近实时分析功能还处在开发阶段;

Druid 使用倒排 Bitmap 索引,Kylin 对历史数据使用 Olap cube 存储;

Kylin 支持 SQL,Druid 不支持 SQL 查询。

踩过的坑

1、时区问题 Druid 切片依赖时间戳,默认时间戳为 UTC,可能会导致切片不正确。需要通过指定 JVM 默认时区的方法指明时区。Caravel 对关系数据库的默认时区支持同样有问题,计划解决后给官方提 PR。

2、Druid 官方文档中有对 protobuf 的支持,实际使用中不支持 include,不支持嵌套结构。基本没有达到可用状态。

3、对非 JSON 的数据,尽量使用标准 CSV 格式。否则各种转转义问题会很麻烦。

4、不要把订单号之类的唯一键作为维度,没有意义。

5、适当选择分片大小。使用中发现通过 MR 索引,实际的索引会在 reduce 步进行,每个 reducer 处理一个分片。所以适当增加 reduce 内存。数据倾斜时可以考虑用多次 MR 索引。


来源:Qunar技术沙龙

声明:数据猿尊重媒体行业规范,相关内容都会注明来源与作者;转载我们原创内容时,也请务必注明“来源:数据猿”与作者名称,否则将会受到数据猿追责。

刷新相关文章

旅游交通大数据——大众旅游时代的“富矿”
旅游交通大数据——大众旅游时代的“富矿”
#榜样的力量#疾控AI分析平台WDCIP——以科技力量贡献“大数据”智慧丨数据猿新冠战“疫”公益策划
#榜样的力量#疾控AI分析平台WDCIP——以科技力量贡献“大数...
张涵诚:大数据招商平台可推动地方供给侧改革
张涵诚:大数据招商平台可推动地方供给侧改革

我要评论

精品栏目

[2017/12/19]

大数据24小时

More>

[2017/12/18-22]

大数据周周看

More>

[2017/12/18-22]

大数据投融资

More>

[2017/12/18-22]

大咖周语录

More>

[2017/12/13-20]

大数据周聘汇

More>

[2017/12/12-19]

每周一本书

More>

返回顶部