V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hailong0707
V2EX  ›  程序员

Apache Kylin 性能优化

  •  2
     
  •   hailong0707 · 2019-06-26 11:47:40 +08:00 · 1365 次点击
    这是一个创建于 1776 天前的主题,其中的信息可能已经有所发展或是发生改变。

    聚合组 Aggregation Groups

    Cube Designer 的 Advanced Setting 中可以配置 Aggregation Groups。 理论上 N 维度 Cube 会构建 2^N 个 Cuboid,随着维度的增多,Cuboid 数量会指数增长,存储空间占用增大,构建时间增长。聚合组的目的是对维度分组,减少不必要的维度组合,从而减少 Cuboid 的数量。 4 维度 Cube 构建 16 个 Cuboid

    分组之后的维度集合支持必要维度,层级维度,联合维度 3 种配置。

    必要维度 Mandatory Dimension

    用户对一个或几个维度特别敏感,所有的查询中都存在 GROUP BY 这些维度,则可以把这些维度配置为必要维度。 A 为必要维度

    层级维度 Hierarchy Dimensions

    具有层级关系的维度,例如国家 country,省份 province,城市 city。这三个维度的查询有以下三类:

    1. group by country
    2. where country='xxx' group by province
    3. where country='xxx' and province='zzz' group by city

    A,B,C 为层级维度

    联合维度 Joint Dimensions

    联合维度表示不可分割的维度集合。 A,B,C 为联合维度

    Rowkeys 优化

    Kylin 使用 HBase 作为 Cube 的存储引擎。HBase 是 Hadoop 生态的 Key-Value 数据库,支持按 Key 随机查询和写入,这个 Key 在 HBase 中叫做 Rowkey。

    维度编码 Encoding

    对维度编码,可以将维度值转化为长度一致的字节,合适的编码方式能够有效减少对空间的占用,加速查询效率。

    1. dict 字典编码,将提取纬度的唯一值在内存中构造字典,Rowkey 使用字典的 key 替换纬度值。 字典常驻内存,对查询影响很小,但是字典不能超过缓存大小,否则在 Cube build 过程中会发生缓存溢出。默认 dict 编码字段基数在5,000,000以内,可以通过kylin.dictionary.max.cardinality修改,这种情况更好的做法是使用其他编码类型。 dict 字典适用中低基维度,如地区信息,国家,省份,城市。

    2. fixed_length 使用固定长度 N 存储维度值,超过长度部分会截断。如果 N 很大,会造成 Rowkey 过长,HBase 性能下降。 fixed_length 适用超高基场景,如电话号码,IP 等。

    3. fixed_length_hex 针对值为十六进制的维度,比如 Base64 之后的值。

    4. integer 整数类型,不做编码转换。Length长度范围为 1~8,支持的整数范围[-2^(8*N-1) ~ 2^(8*N-1)]

    5. date 日期类型。适用 3 个字节编码。

    6. time 时间戳类型,毫秒部分会忽略。

    7. boolean 适用 1 个字节表示布尔值。

    维度顺序

    HBase 中的数据按照 Rowkey 的字典排序顺序存储。

    1. 查询频率高的维度放在低频率之前
    2. 高基维度放在低基维度之前

    分片维度 Shard By

    Rowkeys 可以为一个(最多也只有一个)维度配置Shard By值为true。 Cube 在构建过程中需要 将中间表的数据分布到 HDFS 节点,默认 partition 方式是随机。如果指定分片维度,则使用分片维度做 partition。partition 的目的是防止中间表大小差异造成数据倾斜,因此 Shard By 维度应该使用高基维度,以使分片粒度足够小,能够加速之后的 MR 计算任务。

    注意分片维度和 Cube 的 Partition 维度不同,前者作用于构建阶段,后者是用于分割时间段以支持增量构建

    字典优化 Advanced Dictionaries

    1. Global Dictionary 用于精确计算 COUNT DISTINCT 的字典, 它会将一个非 integer 的值转成 integer,以便于 bitmap 进行去重。如果你要计算 COUNT DISTINCT 的列本身已经是 integer 类型,那么不需要定义 Global Dictionary。Global Dictionary 会被所有 segment 共享,因此支持在跨 segments 之间做上卷去重操作。请注意,Global Dictionary 随着数据的加载,可能会不断变大。
    2. Segment Dictionary 用于精确计算 COUNT DISTINCT 的字典,与 Global Dictionary 不同的是,它是基于一个 segment 的值构建的,因此不支持跨 segments 的汇总计算。如果你的 cube 不是分区的或者能保证你的所有 SQL 按照 partition_column 进行 group by, 那么你应该使用 “ Segment Dictionary ” 而不是 “ Global Dictionary ”,这样可以避免单个字典过大的问题。
    3. 字典复用 Reuse 如果 A 列是是 B 列的子集,则 A 列可以复用 B 列的字典。

    列簇优化 Advanced ColumnFamily

    Kylin 默认将所有度量放在 HBase 的 1 个列簇中。 每个 COUNT DISTINCT 度量使用 bitmap 存储明细数据,这样的度量基数一般都很大。多个这样的度量存储在同 1 个列簇计算量很大,可以将超过一个的 COUNT DISTINCT 或 TopN 度量, 放在更多列簇中(不同的列簇保存在不同的 Store 中),以优化与 HBase 的 I/O。 注意,HBase 的列簇最好控制在 2-3 个

    Normal 普通列 VS Derived 派生列

    在 LookupTable 可以设置列为Normal或者Derived。 当一个或多个维度能够从另一个维度(一般为事实表的外键)推导出来,可以考虑将这个列设置为派生列。派生列不会参与 Cube 计算。 New ModelNew Join Condition,左边为事实表的外键,右边为 lookup 表的主键

    精确去重 Distinct Count

    为了支持任意粒度的上卷聚合,精确去重需要保存明细数据,所以使用 Bitmap 保存精确去重度量数据。Kylin 使用 RoaringBitmap 库。 RoaringBitmap 只支持 Int 类型的数据,所以 Kylin 引入了全局字典,以保证在不同 Segment 上,String 到 Int 的映射一致。全局字典的核心数据结构是 AppendTrieDictionary。

    近似去重

    Kylin 的近似去重,基于 HLL (HyperLogLog)实现。 简单来说,每个需要被计数的值都会经过特定 Hash 函数的计算,将得到的哈希值放入到 byte 数组中,最后根据特定算法对 byte 数据的内容进行统计,就可以得到近似的去重结果。

    膨胀率 Expansion Rate

    膨胀率是指 Cube 大小 /原始 Table 大小。膨胀率应该控制在 10 倍以内。 影响 Cube 大小的因素:

    1. Cube 维度数量很多,没有进行 Cuboid 剪枝优化,导致 Cuboid 数量巨大
    2. Cube 中存在高基维度,造成包含这类维度的 Cube 很大
    3. 存在占用空间很大的度量,比如 COUNT DISTINCT

    超高基维度 UHC

    UHC 代表 Ultra High Cardinality,即超高基数。基数表示维度不同值的数量。通常,维度的基数从数十到数百万。如果超过百万,我们将其称为超高基维度,例如:用户 ID,电话号码等。

    参考文档

    诸葛葛说

    目前尚无回复
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   983 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 21:55 · PVG 05:55 · LAX 14:55 · JFK 17:55
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.