查看原文
其他

滴滴:Apache Kylin 自助式治理与演进之路(下)

靳国卫 apachekylin 2022-04-23

在上期的文章中,滴滴出行的技术专家靳国卫分享了 Kylin 在滴滴的平台架构、相关数据、集群服务治理(戳此处查看)。本期文章将接着介绍滴滴对 Kylin 字典的改造。


字典改造

下面讲一个实际案例,滴滴对于字典的改造——全域字典。


1. 如何改造

首先,简单介绍下 Kylin 默认支持精确去重的字典是全局字典,限制是只能实现 Cube 内的复用。适用方式是设定计算指标为 “count_distinct”,选择 Return Type为”precisely (More Memory and Storage Need)”, 并在”Advanced Dictionaries”处选择“Builder Class :org.apache.kylin.dict.GlobalDictionaryBuilder”。


通过名字可以了解到,滴滴这边实现的字典是可以支持跨 Cube 使用,所以叫”全域字典”。演变过程分两步:

第一步,MR-Hive 字典实现字典编码外置 Hive 表;

第二步,MR-Hive 全域字典改造实现 Cube 间依赖。


2. 案例

结合一个案例来说明下,如上图所示,是一个效果评测平台:

  1. 圈定一部分标签数据;

  2. 投放前分析数据在过去几个月的历史数据;

  3. 投放后持续跟进效果。


在此过程中进行效果评估的数据是固定的,但是需要计算留存、用户数等指标,所以用到 Kylin 的精确去重指标。可是字典只需要构建一份就可以了,其他的数据可以公用这一份数据,这样就可以缩减 Kylin 的构建时间并减小 Kylin 的 Job 节点构建的压力。


为什么可以实现 Kylin 字典的外置?一起梳理下基本流程和关键核心点:

  1. Kylin 的上卷、下钻的的精确去重得益于其实现的全局字典。

  2. Build Dimension Dictionary 过程是将 uid 编码成 int 数值的过程,此过程是在 Job 节点单机完成的。

  3. Build Base Cuboid 这步骤主要做两件事情:

    1)将原始数据的 uid 替换成编码后的 int 数值。

    2)做一个全维度(cube 设置的全部维度)的 group by 操作,此时 count_distinct 函数的计算结果会转化成一个 bitmap(RoaringBitmap),此对象可以做或、与的按位操作。

  4. 在 Kylin 返回给可客户端的时候只需要做一个 bitmap(RoaringBitmap).count() 操作,就可以得到结果。


我们从上边的流程可以分析出我们需要做的事情有两个:

  1. 模拟Build Dimension Dictionary过程,充分利用计算集群的能力实现 uid 与 int 编码的过程,并将结果存入 Hive。

  2. 改造 Build Base Cuboid 过程,实现高效的字典替换。


3. 效果

上图简单总结了做全域字典的初衷、改造的可行性思考、取得的效果。

用上图展示下实际的使用效果,右边是默认的全局字典的配置后的元数据展示,左边是全域字典的配置形式。可以看到字典在 reuse 的时候其实引用的是其他 cube 的列,同时也设定了引用的 model 和 cube,从截图可以看出它们来自不同的 cube。


Kylin 本身是不提供调度依赖的,但是实际企业生产是要有依赖关系的。滴滴的做法是在 cube 的字典构建完成时,在 hdfs 记录一个 success 信息,依赖此字典的 cube 把此依赖配置到当前 cube 的依赖,这样就从企业生产环境的角度实现了 cube 间调度的相互依赖。

此处列举几个做这件事情的外因:

  1. 任务构建对集群的压力:如果不使用全域字典,则每个 cube 都需要构建一遍字典,这样任务的构建时间就会变长。job 节点的并发有限会造成任务的等待时间变长,字典构建这一步是在 job 节点单机完成的,对 cpu 和网络的压力也比较大。

  2. 影响 Hadoop 集群的稳定性:全局字典是以文件的方式存在于 HDFS 上的,使用的是AppendTrieDictionary,实际进行判定字典插入和查询是按照 Slice 为单位进行交互判定的。所以当字典比较大并且事实表的纪录条数比较多时,就会频繁的从 HDFS 获取数据对比,这时候网络压力就会很大。上图为滴滴一个构建 cube 启动后 hadoop 集群网络的飙升情况。

MR-HIVE 字典的实现思路:

  1. 创建一个 kylin-flat-table 的 group_by 表,将配置的全域字典列做一个 group by 操作,写入对应的分区中,因为是字典所以保留一条纪录即可;

  2. 创建一个 cube 的 global_dict 表,设计的数据结构为 key、dict value、partition;

  3. 将 global_dict 表和 group_by 表做一个增量计算则可以获取到增量字典,完成 global_dict 的编码工作;

  4. 将 kylin-flat-table 表和 global_dict 关联,替换 kylin-flat-table 中的 uid 为编码后的 int 字典值;

  5. 根据之前讲的 Build Base Cuboid原理,就是实现了全域字典外置 Hive 字典的实现。


此图是 global_dict 表和 group_by 表做一个增量计算的 SQL。当字典值比较大的时候,row_number() 排序的效率很低,构建会长时间卡住。经过分析发现是全局排序的问题,那有没有解决办法呢?

经过调研发现,Hive 在实现全局 order by 的时候并没有这样的性能瓶颈。调研发现其使用的是 Hadoop 提供的 TotalOrderPartitioner,因此借鉴此实现优化了 row_number() 的性能瓶颈

基于全域字典的外置 Hive 特点,在滴滴延伸出以下几个场景:

  1. Hive 字典已经外置,那么字典的构建可以通过 ETL 来实现,只需要满足global_dict字典表的结构即可,不需要再 kylin 流程中构建了。

  2. 在以往的用户分析中,用户只能分析出用户的结果数。经过此改造后结合滴滴实现的count_distinct_detail函数,分析人员不仅可以知道用户数是多少,并且知道是谁,从而可以和广告营销等系统打通。

  3. 字典外置可以容易的实现 cube 间的依赖,让数据的组织更加合理、高效。



社区福利 ▼ 


推荐 4 个 Apache 顶级项目的官方公众号,希望对大家了解开源大数据生态,扩展技术视野有所帮助。


HBase 技术社区

研究探讨 Apache HBase 内核原理,源码剖析,周边生态以及实践应用,汇集众多Apache HBase PMC & Committer以及爱好使用者,提供一线Apache HBase企业实战以及Flink集成等资讯。


Apache Pulsar

Apache Pulsar 是下一代云原生流数据平台,助力企业快速分析实时数据,激活数据价值,实现 C 位出道。这里是 Pulsar 前沿技术的传播圣地,也是技术爱好者、开发者和终极用户时刻关注的技术平台。我们定时分享 Pulsar 优质内容,包括社区活动、技术文章、用户案例、行业动态和热点话题等,让你全面拥抱 Pulsar 的一手讯息。Apache Pulsar,助力千万企业和技术人开疆拓土、共同成长。


Ververica

由 Apache Flink Community China 运营管理,旨在联合国内的 Flink 大 V,向国内宣传和普及 Flink 相关的技术。公众号将持续输出 Flink 最新社区动态,入门教程、Meetup 资讯、应用案例以及源码解析等内容,希望联合社区同学一起推动国内大数据技术发展。


Apache Kylin

介绍 Kylin 的功能特性、应用案例、经验分享、社区资讯、活动等。开源大数据分布式 OLAP 引擎 Apache Kylin 于 2014 年开源,在 2015 年和 2016 年连续获得 InfoWorld 的 BOSSIE 奖:年度最佳开源大数据工具奖,发展至今在全球已经拥有超过 1000 家企业用户。作为首个被 Apache 软件基金会认证的由中国人主导的顶级开源项目,Kylin 为万亿数据提供亚秒级查询,并可以和现有的 Hadoop/Spark 及 BI 无缝集成。


往期案例与实践

滴滴:Apache Kylin 自助式治理与演进之路(上)

问题排查 | Kylin 2.0-HBase 0.98 重启

Kylin 在满帮集团千亿级用户访问行为分析中的应用

解读 Kylin 3.0.0 | 更敏捷、更高效的 OLAP 引擎

向 Kylin 添加实时 OLAP 能力


点“阅读原文”获取分享PPT

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存