Druid 介绍和应用

Druid 介绍

提及 Druid,你们首先想到的是阿里的 Druid 数据库链接池,而本文介绍的 Druid 是一个在大数据场景下的解决方案,是须要在复杂的海量数据下进行交互式实时数据展示的 BI/OLAP 工具。数据库

它有三个特色:json

  • 处理的数据量规模较大。后端

  • 能够进行数据的实时查询展现。安全

  • 它的查询模式是交互式的,这也说明其查询并发能力有限。网络

目前 Druid 普遍应用在国内外各个公司,好比阿里,滴滴,知乎,360,eBay,Hulu 等。架构

Druid 之因此可以在 OLAP 家族中占据一席之地,主要依赖其强大的 MPP 架构设计,关于它的架构,这里就不展开描述了,感兴趣的同窗能够登录官网 druid.io 进行了解。并发

除了 MPP 架构外,它还运用到了四点重要的技术,分别是:负载均衡

  • 预聚合工具

  • 列式存储学习

  • 字典编码

  • 位图索引

预聚合算是 Druid 的一个很是大的亮点,经过预聚合能够减小数据的存储以及避免查询时不少没必要要的计算。

因为 OLAP 的分析场景大多只关心某个列或者某几个列的指标计算,所以数据很是适合列式存储。

在列式存储的基础之上,再加上字段编码,可以有效的提高数据的压缩率,而后位图索引让不少查询最终直接转化成计算机层面的位计算,提高查询效率。

Druid 既然是 OLAP 工具,那它和其余 OLAP 工具备哪些差别呢?

 

图 1:OLAP 工具的对比

从上图能够看出,Kylin 和 Druid 总体上相比较其余两个仍是颇有优点的:

相比较 Kylin,Druid 没有模型管理和 cube 管理的能力,Kylin 没法提供实时查询。

相比较 ES,Druid 的优点在于聚合计算,ES 的优点在于查明细,在苏宁,对 Druid 的使用,通常应用在须要对数据进行实时聚合查询的场景。

Druid的应用场景

门店 App 系统

门店 App 系统是一款集数据服务、销售开单、会员营销、收发盘退、绩效管理、V 购用户沟通、学习中心等于一体的门店店员移动工做平台,其销售界面以下所示:

图 2:销售界面

 

图 3:客流界面

 

门店 App 业务大体状况以下:

  • 数据量:保存近几年的数据。

  • 数据接入方式:Kafka 实时数据接入,隔天离线数据覆盖昨天数据。

  • 查询方式:实时查询。

  • 业务实现:topN 实现销售额曲线展现,groupby 分组楼层客流分布,timeserise 作天汇总。

报表系统

 

大体状况以下:

  • 数据量:保存近几年数据。

  • 数据接入方式:Kafka 实时数据接入。

  • 查询方式:实时查询。

  • 业务实现:topN 实现销售饼图展现,groupby 分组实现大区销售排名。

基于 OLAP 引擎的平台架构

为保证数据的一致性和统一性,该平台基于 OLAP 引擎,为集团各个业务提供统一的维度指标分析系统:

  • 百川系统经过 OLAP 引擎构建模型,OLAP 引擎根据业务需求,将模型拆分红若干个 cube,存储到底层的 Druid,Hive,PG 和 ES。咱们称这个过程为模型加速,另外,百川系统自身会构建各类各样的指标。

  • 业务方,好比天工,诸葛等系统经过百川提供的指标,选择其中一个或多个进行报表的构建,其查询请求会发送到百川系统。

  • 百川系统构造 SQL 语句,再把请求发送到 OLAP 引擎,OLAP 引擎经过底层的 Spark 平台,解析 SQL 语句,将请求路由到 Druid,ES,Hive 和 PG,其中,时序化数据的聚合查询,将路由到 Druid 平台,最后查询结果一层一层汇总到上层的业务系统。

  • 整个系统的监控,经过云迹系统、华佗系统等进行监控,将系统日志接入云迹,将系统的 metric 信息接入华佗。

随着 Druid 平台建设的不断推动,使用 Druid 的业务也愈来愈多,在使用的过程当中也会遇到各类各样的问题,下文总结了苏宁业务开发人员在使用 Druid 中遇到的一些问题,但愿对正在阅读本文的读者有些帮助。

Druid 使用建议

本小节主要想结合实际问题,给你们提供一些 Druid 的使用建议,供你们参考。

①什么样的业务适合用 Druid?

建议以下:

  • 时序化数据:Druid 能够理解为时序数据库,全部的数据必须有时间字段。

  • 实时数据接入可容忍丢数据(tranquility):目前 tranquility 有丢数据的风险,因此建议实时和离线一块儿用,实时接当天数据,离线次日把今天的数据所有覆盖,保证数据完备性。

  • OLAP 查询而不是 OLTP 查询:Druid 查询并发有限,不适合 OLTP 查询。

  • 非精确的去重计算:目前 Druid 的去重都是非精确的。

  • 无 Join 操做:Druid 适合处理星型模型的数据,不支持关联操做。

  • 数据没有 update 更新操做,只对 segment 粒度进行覆盖:因为时序化数据的特色,Druid 不支持数据的更新。

②如何设置合理的 Granularity?

Granularity 设置

首先解释下 segmentGranularity 和 queryGranularity,前者是 segment 的组成粒度,后者是 segment 的聚合粒度。

要求 queryGranularity 小于等于 segmentGranularity,而后在数据导入时,按照下面的规则进行设置。
segmentGranularity(离线数据导入的设置):

  • 导入的数据是天级别之内的:“hour”或者“day”。

  • 导入的数据是天级别以上的:“day”。

  • 导入的数据是年级别以上的:“month”。

须要说明的是,这里咱们仅仅是简单的经过 intervals 进行 segmentGranularity 的设置,更加合理的作法应该是结合每一个 segment 的大小以及查询的复杂度进行综合衡量。

考虑到 tranquility 实时任务的特殊性和数据的安全性,咱们建议实时数据导入时,segmentGranularity 设置成“hour”。

queryGranularity:根据业务查询最小粒度和查询复杂度来定,假设查询只须要到小时粒度,则该参数设置为“hour”。

③须要去重的维度到底需不须要定义到维度列中?

 

若是去重的维度只须要去重计算,没有其余的做用,譬如进行过滤或者做为分组字段,咱们建议不要添加到维度列中,由于不添加的话,这样数据的预聚合效果更好。

④如何选择查询方式?

经常使用的三种查询:

  • select sum(A) from DS where time>? [timeseries]

  • select sum(A) from DS where time>? group by B order by C limit 2 [topN]

  • select sum(A) from DS where time>? group by B,C order by C limit 2[groupby]

没有维度分组的场景使用 timeseries,单维度分组查询的场景使用 topN,多维度分组查询场景使用 groupby。

因为 groupby 并不会将 limit 下推(Druid 新版本进行了优化,虽然能够下推,可是对于指标的排序是不许确的),因此单维度的分组查询,尽可能用 topN 查询。

咱们作的工做

从 Druid 引入苏宁以后,不久便承担起了 OLAP 分析的重任,做为底层核心引擎支撑模型和指标服务,并为集团各条业务线的 OLAP 分析服务,在过去的时间里,咱们作了不少工做,本文列举一些进行说明。

①OCEP(Druid 集群前置 proxy)

OCEP(Druid 集群前置 proxy)

 

OCEP 是 Druid 集群一个前置 proxy,经过它来提供更加完备的 Druid 集群化和服务化能力,并解决当前 Druid 服务存在的各类问题。

它提供的功能主要有:

  • 访问鉴权(针对每一个 datasource 提供 token 访问鉴权,保证数据安全)。

  • 访问审计(对每一个查询都会生成惟一的 queryId,提供完整的请求来源)。

  • 请求拦截(对非预期的访问,制定拦截策略,细化到具体的 datasource 和查询语句)。

  • 请求路由(根据集群名称和 datasource,将请求路由到指定的 Druid 集群,并根据后端 broker 的压力,将请求负载均衡各个 broker 上)。

  • 服务隔离(可设置策略,对于不一样的 datasource 的请求,可路由到指定的 broker 上,实现 broker 隔离)。

②Druid 查询客户端

官方提供的查询方式是经过编写 Json 文件,以 HTTP 的方式请求 Druid,然而这种方式的缺点也很明显,首先 Json 内容书写繁琐,格式极易写错,另外在 Java 开发时,出现问题不利于定位。

 

json语句

 

因而咱们封装了一层 Java API,以下图:

 

③资源隔离

 

不一样业务的数据量有大小之分以及对服务稳定性要求不同,咱们经过如下三点实现业务层面的隔离:

  • Historical 分组:集群设置不一样的 tier,存储不一样的业务数据。

  • Broker 隔离:经过 OCEP 设置 datasource 白名单,不一样的 broker 只提供某个或某几个 datasource 的查询。

  • 冷热数据隔离:经过设置 datasource 的 rule,将冷热数据分别存储在不一样的 tier 中。

  • Druid 白名单控制。

集群稳定性压倒一切,防止控制之外的机器对集群进行无效查询和攻击,咱们经过增长一个 whitelist 的 extension,以模块的方式在服务端进行白名单的控制。

而且能够针对不一样的服务进行控制,将 whitelist 的配置文件写在 Druid 的 metadata 的 config 表中,实现动态更新。

 

图 14:白名单 extension

 

图 15:Druid 白名单配置

④Druid 离线导入时对 intervals 的控制

有些离线导入的任务,占用了 YARN 太多的资源,个别任务消耗了上千个或者上万的 container 资源,分析发现是因为业务设置的 segmentGranularity 不合理,最终会致使 segment 过多,产生不少 HDFS 小文件。

因而咱们在 overlord 服务端,增长参数“druid.indexer.intervals.maxLimit”,对离线任务进行判断。

若是 segmentGranularity 和 interval 设置的不合理,将禁止提交。譬如,segmentGranularity 设置的是小时,interval 设置的间隔是 1 年,这种是不合理的,服务端将禁止数据导入。

 

离线导入对 intervals 的控制参数配置

⑤Coordinator 自动 merge segment 时启动 task 的并发数控制

在集群中,咱们打开了 coordinator 自动 merge segment 的功能,coordinator 默认每隔 30 分钟,启动 merge 线程,扫描全部的 datasource,将太小的 segment 按要求进行合并。

每当一批 segment 符合 merge 要求了,就会请求 overlord 进行启动 merge task。

若是集群内小 segment 不少,merge task 将启动无数个,堵塞 middleManager 的 peon 资源,咱们增长限制 merge task 的并发数的参数,保证每次 merge 线程只启动必定数量的 task。

设置 merge task 的并发数

⑥Druid 监控

监控对于任何一个系统而言都是很是重要的,能够帮助咱们提早预知系统的健康情况,Druid 的监控主要有两点,业务查询状况和平台运行状况。

前者主要包括 datasource 的查询量、查询耗时、网络流量等;后者主要包括各个服务的 gc 状况、cpu 和内存使用状况、空闲 Jetty 线程数等。

咱们的监控方案是 Druid_Common 集群和 Druid_OLAP 集群相互监控,互相存储对方的 metric 信息,而后经过 superset 展现。

 

Druid 的监控方案

将来规划

Druid 在苏宁还有很长一段路要走,不管从查询优化方面仍是集群管理方面,都有不少事情要作。
查询优化方面:

  • 高基数问题:高基数查询一直是 OLAP 查询的一大痛点,新版本虽然支持 limit 下推,但也只是对维度进行排序的时候,才能保证准确性。

  • SQL 支持:进行 Druid 版本升级,提供丰富的 SQL 查询接口。

  • 精准去重:目前 Druid 对去重的计算,不管是 HyperLogLog、ThetaSketch 仍是最新版本提供的 HLLSketch 都是非精确的,后面考虑是否能够经过集成 bitmap 解决。

集群管理方面:

  • Kafkaindex service 使用:tranquility 的时间窗口限制会形成延迟很大的数据丢失,并且实时 peon 的管理不够灵活,某些场景下,也会形成数据丢失。

而 Kafka index service 的实时 peon 调用了 Kafka 底层的 API,管理更灵活,依赖 Kafka 实现数据的不丢不重。

  • Datasource 跨集群迁移:Druid 不管是数据导入仍是数据查询都很是依赖 Zookeeper,当集群规模愈来愈大,datasource 愈来愈多的时候,Zookeeper 也许会成为瓶颈。

这样的话,就须要作 datasource 的迁移,而迁移工做涉及到 datasource 元数据和 HDFS 数据的迁移,如何让迁移工做轻量化,是咱们须要思考的。

相关文章
相关标签/搜索