Apache Kylin 入门系列目录算法
因为业务需求不尽相同,本文不使用具体的案例进行演示,文章会更加倾向于对构建过程当中的选项和注意事项进行全方位阐述。编程
Cube Info 界面主要填写 Cube 的一些基本信息,首先要选择一个数据模型,而后填写 Cube 名称,Cube 名称全局惟一不能重复;Cube 信息填写完成后点击 “Next” 进入下一步。架构
Dimensions 是维度选择界面,从数据模型的维度中选择一些列做为 Cube 的维度,这个算是 Cube 构建过程当中第一个比较重要的环节,这里的设置会影响到生成的 Cuboid 数量,进而影响 Cube 的数据量大小。post
在选择维度时,每个维度列能够做为普通维度(Normal),也能够做为衍生维度(Derived)。相对于普通维度来讲,衍生维度并不参与维度的 Cuboid,衍生维度对应的外键(FK)参与维度 Cuboid,从而下降 Cuboid 数。在查询时,对衍生维度的查询会首先转换为对外键所在维度的查询,所以会牺牲少许性能(大部分状况下能够接受)。性能
维度选择完成后,须要选择度量聚合的方式,比较常规的聚合方式有:COUNT、SUM、MIN、MAX、PERCENTILE,下面将详细介绍其余几种聚合方式。优化
Top-N 度量,旨在在 Cube 构建的时候预计算好须要的 Top-N;在查询阶段,就能够迅速的获取并返回 Top-N 记录,这样查询性能就远远高于没有 Top-N 预计算结果的 Cube。编码
例如:全国二氧化碳污染物总和的省份排名,结果是省份排名,须要测量的是污染物的总和,所以 Group By 须要设置为 污染物类型。设计
TOP N 表示最终获取的前 N 名的排序是比较准确的,例如 TOP 10 表示最终的前 10 名是比较准确的(维度的基数很是大时存在偏差),可是不表明只能取前 10 个(Limit 10),可使用其余数字,例如 Limit 500,只是返回更多内容时,精准度没有保证。3d
使用 TOP-N 时,排序度量字段和 Group By 字段会组合在一块儿,造成一个字段进行存储,用户须要 Top 100 的结果,Kylin 对于每种组合条件值,保留 Top 5000 (50倍)的纪录, 并供之后再次合并。code
Count_Distinct 度量有两个实现:
越精确消耗的存储空间越大,大多数场景下 HyperLogLog 的近似实现便可知足需求。
在分析场景中,常常存在对某个 id 进行过滤,但查询结果要展现为 name 的状况,好比user_id
和user_name
。这类问题一般有三种解决方式:
select name, count(*) from table where id = 1 group by id,name
,这种方式的问题是会致使维度增多,致使预计算结果膨胀;Volatile Range
天的 cube segments;假设 Volatile Range 设置为 7,则最近 7 天内生成的 cube segments 不会被自动合并;1970-01-01 08:00:00
默认为分区起始时间。高级设置主要用于 Cuboid 的剪枝优化,经过聚合组(Aggregation Group)、必要维度(Mandatory Dimension)、层级维度(Hierarchy Dimension)、联合维度(Joint Dimension)等方式,可使得 Cuboid 的组合在预期范围内。
根据查询的维度组合,能够划分出维度组合大类,这些大类在 Kylin 里面被称为聚合组。例如查询需求为:污染物排放量在特定的时间范围内,各个区域(省、市、区县三个级别)的排名以及各个流域(1、2、三级流域)的排名。
上述的查询需求就能够氛围两个聚合组:
若是只使用一个聚合组,区域维度和流域维度就很产生不少组合的 Cuboid,然而这些组合对查询毫无用处,此时就可使用两个聚合组把区域和流域分开,这样即可以大大减小无用的组合。
Mandatory 维度指的是那些老是会出现 在Where 条件或 Group By 语句里的维度。
固然必须存在不必定是显式出如今查询语句中,例如查询日期是必要字段,月份、季度、年属于它的衍生字段,那么查询的时候出现月份、季度、年这些衍生字段等效于出现查询日期这个必要字段。
Hierarchy 是一组有层级关系的维度,例如:国家->省->市,这里的“国家”是高级别的维度,“省”“市”依次是低级别的维度;用户会按高级别维度进行查询,也会按低级别维度进行查询,但在查询低级别维度时,每每都会带上高级别维度的条件,而不会孤立地审视低级别维度的数据。也就是说,用户对于这三个维度的查询能够归类为如下三类:
有些维度每每一块儿出现,或者它们的基数很是接近(有1:1映射关系),例如 “user_id” 和 “email”。把多个维度定义为组合关系后,全部不符合此关系的 cuboids 会被跳过计算。
就 Joint Dimension (A, B)
来讲,在 group by 时 A, B 最好同时出现,这样不损失性能。但若是只出现 A 或者 B,那么就须要在查询时从 group by A,B
的结果作进一步聚合运算,会下降查询的速度。
Kylin 以 Key-Value 的方式将 Cube 存储到 HBase 中,HBase 的 key,也就是 Rowkey,是由各维度的值拼接而成的;为了更高效地存储这些值,Kylin 会对它们进行编码和压缩;每一个维度都可以选择合适的编码(Encoding)方式,默认采用的是字典(Dictionary)编码技术;字段支持的基本编码类型以下:
dict
:适用于大部分字段,默认推荐使用,但在超高基状况下,可能引发内存不足的问题;boolean
:适用于字段值为true, false, TRUE, FALSE, True, False, t, f, T, F, yes, no, YES, NO, Yes, No, y, n, Y, N, 1, 0
;integer
:适用于字段值为整数字符,支持的整数区间为[ -2^(8N-1), 2^(8N-1)]
;date
:适用于字段值为日期字符,支持的格式包括yyyyMMdd、yyyy-MM-dd、yyyy-MM-dd HH:mm:ss、yyyy-MM-dd HH:mm:ss.SSS
,其中若是包含时间戳部分会被截断;time
:适用于字段值为时间戳字符,支持范围为[ 1970-01-01 00:00:00, 2038/01/19 03:14:07]
,毫秒部分会被忽略,time编码适用于 time, datetime, timestamp 等类型;fix_length
:适用于超高基场景,将选取字段的前 N 个字节做为编码值,当 N 小于字段长度,会形成字段截断,当 N 较大时,形成 RowKey 过长,查询性能降低,只适用于 varchar 或 nvarchar 类型;fixed_length_hex
:适用于字段值为十六进制字符,好比 1A2BFF 或者 FF00FF,每两个字符须要一个字节,只适用于 varchar 或 nvarchar 类型。各维度在 Rowkeys 中的顺序,对于查询的性能会产生较明显的影响;在这里用户能够根据查询的模式和习惯,经过拖曳的方式调整各个维度在Rowkeys上的顺序。推荐的顺序为:Mandatory 维度、where 过滤条件中出现频率较多的维度、高基数维度、低基数维度。这样作的好处是,充分利用过滤条件来缩小在 HBase 中扫描的范围,从而提升查询的效率。
指定 ShardBy 的列,明细数据将按照该列的值分片;没有指定 ShardBy 的列,则默认将根据全部列中的数据进行分片;选择适当的 ShardBy 列,可使明细数据较为均匀的分散在多个数据片上,提升并行性,进而得到更理想的查询效率;建议选择基数较大的列做为 ShardBy 列,以免数据分散不均匀。
Mandatory Cuboids
: 维度组合白名单,指定须要构建的 cuboid 的维度的组合;Cube Engine
: Cube 构建引擎,有两种:MapReduce 和 Spark;若是你的 Cube 只有简单度量(SUM, MIN, MAX),建议使用 Spark;若是 Cube 中有复杂类型度量(COUNT DISTINCT, TOP_N),建议使用 MapReduce;Global Dictionary
:用于精确计算 COUNT DISTINCT 的字典, 它会将一个非 integer 的值转成 integer,以便于 bitmap 进行去重;若是你要计算 COUNT DISTINCT 的列自己已是 integer 类型,那么不须要定义 Global Dictionary; Global Dictionary 会被全部 segment 共享,所以支持在跨 segments 之间作上卷去重操做。Segment Dictionary
:另外一个用于精确计算 COUNT DISTINCT 的字典,与 Global Dictionary 不一样的是,它是基于一个 segment 的值构建的,所以不支持跨 segments 的汇总计算。若是你的 cube 不是分区的或者能保证你的全部 SQL 按照 partition_column 进行 group by, 那么你应该使用 “Segment Dictionary” 而不是 “Global Dictionary”,这样能够避免单个字典过大的问题。Advanced Snapshot Table
: 为全局 lookup 表而设计,提供不一样的存储类型;Advanced ColumnFamily
: 若是有超过一个的 COUNT DISTINCT 或 TopN 度量, 你能够将它们放在更多列簇中,以优化与HBase 的I/O。Kylin 使用了不少配置参数以提升灵活性,用户能够根据具体的环境、场景等配置不一样的参数进行调优;Kylin 全局的参数值可在 conf/kylin.properties
文件中进行配置;若是 Cube 须要覆盖全局设置的话,则须要在此页面中指定,这些配置项将覆盖项目级别和配置文件中的默认值。
你能够概览你的 cube 并返回以前的步骤进行修改,点击 Save
按钮完成 cube 建立。
若是你开启了 Cube Planner,当 Cube 保存后能够到 Planner 标签页查看 Cuboid 的个数以及各个维度的组合状况,这可以很直观的帮助你了解你的维度组合状况,若是与预想的有出入能够随时对 Cube 进行调整。
Any Code,Code Any!
扫码关注『AnyCode』,编程路上,一块儿前行。