赞
踩
Kylin 官方现在关于精确去重的blog Use Count Distinct in Apache Kylin 是基于Kylin 1.5.3的,其中的使用方式和优化方法已经过时,本文将基于Kylin 2.3.0 介绍精确去重和全局字典的用法,调优,FAQ和核心原理。
本文的主要内容如下:
如上图,编辑指标时Expression选择COUNT_DISTINCT,Return Type 选择 Precisely。 如果你的精确去重列的基数很小,你就已经可以愉快地利用 Kylin 进行精确去重计算了。
当精确去重指标列的基数达到数千万,数亿,或者有多个精确去重指标时,我们就需要进行一些优化。大家可以根据下面的 Case 进行优化,不同的优化方法是可以叠加的。
如果 1 个 Cube 中有多个全局字典列,且存在A列是B列子集的情况,我们就可以让A列复用B列的全局字典。比如日支付用户数一般就是日活跃用户数的子集,这种关系一般在ETL生产中表现为 if (pay = true, uuid, null) as pay_uuid
,我们就可以让 pay_uuid 复用 uuid 的全局字典,如下图:
如果1个Cube有1个或者多个精确去重指标,但是只有1个超高基数列,像PV,UV,订单量这种去重指标,我们可以配置以下参数来优化:
kylin.source.hive.flat-table-cluster-by-dict-column=LOAD_UUID(精确去重指标的列名,不需要加Hive表名)
这个参数的原理是在Cube构建的第2步 “Redistribute Flat Hive Table” 中将Hive表数据按照配置的列Cluster by,让Hive表数据按照Cluster by列有序,以此来减少 “Build Base Cuboid” 这一步对精确去重指标编码时全局字典的内存置换次数。
如果一个Cube中同时有用户数和设备数这种超高基数的精确去重指标,可以考虑拆分成两个cube,转化成Case2,如果不能拆分成两个Cube,就需要增大"Build Base Cuboid" 这一步MR的内存,可以配置以下参数:
kylin.source.hive.flat-table-cluster-by-dict-column=基数最高的精确去重列名 (不需要加Hive表名)
kylin.engine.mr.base-cuboid-config-override.mapred.map.child.java.opts = -Xmx4g
kylin.engine.mr.base-cuboid-config-override.mapreduce.map.memory.mb = 4500
如果你的精确去重指标只需要按天进行去重,那么可以用 Segment Dictionary 代替 Global Dictionary 。 如图:
按天进行精确去重可以理解为你的 SQL 会按照 dt 字段 Group by,不会有类似下面的SQL:
SELECT A, B, count(distinct uuid),
FROM table
WHERE dt between '20170125' and '20170224'
使用 Segment Dictionary 的优点是构建速度会十分快,因为 Segment Dictionary 是基于 Segment 粒度的,不是全局的。
如果你的Cube是非分区的,每天全量构建,那么和Case 4一样,也可以用 Segment Dictionary 代替 Global Dictionary。
如果你的Cube有10多个甚至几十个精确去重指标,且大多数查询一次只会查询1个或者几个精确去重指标,那么可以考虑将精确去重指标拆分到多个列族,这样做到好处是可以加速查询,Kylin默认是把所有精确去重指标都放在HBase的1个列族中。拆分列族是在Cube编辑的第5步的Advanced ColumnFamily部分,如图:
kylin.env.hdfs-working-dir+resources/GlobalDict/dict+/sourceTable+/sourceColumn
问题1:
Build Base Cuboid" java.lang.IllegalArgumentException: Value XXX not exists!
2017-04-14 17:14:19,309 ERROR [main] org.apache.kylin.engine.mr.steps.BaseCuboidMapperBase: Insane record: [17184, 2450, 24205, 440800, C, 6, 4, 2, 7.7, -998, 0, 0, 17.5, 17.5, 17.5, 17.5, 17.5, 17.5, 1, 1, 1, 20170116~20170122, 湛江, 团购android, 团购app, 团购, 未知, \N, \N, \N, \N, \N, 0, �Q;���=�����1 �6,� �_����;���7�, ��������~)� ����������[, �Q;���=�����1 �6,� �_����;���7�, ��������~)� ����������[, �Q;���=�����1 �6,� �_����;���7�, ��������~)� ����������[, \N, \N, \N, 315174395
java.lang.IllegalArgumentException: Value '�Q;���=�����1 �6,� �_����;���7�' (\xEF\xBF\xBDQ;\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD=\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD1 \xEF\xBF\xBD6\x05,\xEF\xBF\xBD \xEF\xBF\xBD_\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD\xEF\xBF\xBD;\xEF\xBF\xBD\x12\x00\xEF\xBF\xBD\xEF\xBF\xBD7\xEF\xBF\xBD) not exists!
at org.apache.kylin.common.util.Dictionary.getIdFromValueBytes(Dictionary.java:162)
at org.apache.kylin.dict.AppendTrieDictionary.getIdFromValueImpl(AppendTrieDictionary.java:153)
at org.apache.kylin.common.util.Dictionary.getIdFromValue(Dictionary.java:98)
at org.apache.kylin.common.util.Dictionary.getIdFromValue(Dictionary.java:78)
at org.apache.kylin.measure.bitmap.BitmapMeasureType$1.valueOf(BitmapMeasureType.java:118)
kylin.job.error-record-threshold = 100 //该参数表示每个mapper可以容忍的异常记录数,默认是0。
问题2:
Build Base Cuboid
这一步Mapper 进度很慢或者 Timed out after 600 secs精确去重指标实现的两个核心难点:
难点的解决方案:
无需上卷的精确去重查询优化:
前面提到,为了支持任意粒度的上卷聚合,我们使用Bitmap存储精确去重指标。所以在查询时,我们需要先从HBase端将整个Bitmap传输给Kylin的QueryServer,Kylin的QueryServr再根据Bitmap计算出 去重值。但是在实际的使用场景中,用户的一些甚至多数精确去重查询是不需要上卷聚合的, 比如用户的Cube按照dt列分区,且已经预计算好(A,dt)的Cuboid,那么下面的SQL查询时在HBase端和Kylin的QueryServer端都是无需聚合的:
SELECT A, count(distinct uuid),
FROM table
WHERE dt between '20170125' and '20170224'
group by dt, A
针对上面提到的场景,我们进行了优化,符合优化规则的查询会在HBase端直接返回最终的去重值,该优化可以将精确去重的查询提高一个数量级,原本需要几秒的查询优化后只需数百毫秒;同时也降低了Kylin QueryServr的内存使用。
全局字典的意义是保证所有Value映射到全局唯一且连续的Int ID ,唯一是保证精确去重查询可以跨Segment上卷,连续的原因是RoaringBitmap对连续的值可以进行更好的压缩。全局字典实现的几个核心难点:
难点的解决方案:
虽然Kylin的精确去重在性能和稳定性方面相比最初已经有了显著的提升,已经在企业级的生产环境中广泛使用,但是依然存在以下痛点:
所以在新的一年,我们会对Kylin的精确去重指标进行继续优化并探索新的方案,比如:有没有可能移除全局字典,RoaringBitmap的计算移到堆外,RoaringBitmap的分布式化等。大家有好的想法也欢迎随时交流。
我也相信,Kylin的精确去重会越来越易用,越高效,越稳定。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。