Apache Kylin(麒麟)是由eBay开源的分布式分析引擎,提供Hadoop之上的SQL查询接口及多维分析(OLAP)能力以支持超大规模数据。底层存储用的是HBase,数据输入与cube building用的是Hive,中间数据存储用的是HDFS。
适用于海量数据的超快OLAP引擎, 降低百亿数据规模下的查询延时。
ANSI SQL查询接口,支持大部分ANSI SQL查询功能。
交互式查询能力。 查询延时控制在亚秒级, 为hadoop提供交互式查询能力。
MOLAP。 用户事先定义cube模型, 并使用kylin从原始数据集离线构建cube。
BI工具无缝集成, 目前能够与tableau集成(使用ODBC)。
1 测试环境
1.1 操作系统
Red Hat 7.2
1.2 组件版本
组件 | 版本 |
JDK | 1.7.0_79 |
hadoop | 2.6.0-cdh5.7.2 |
Hbase | 1.2.0-cdh5.7.2 |
Hive | 1.1.0-cdh5.7.2 |
zookeeper | 3.4.5-cdh5.7.2 |
kylin | Apache v1.5.3-Hbase1.x |
1.3 安装部署
软件包下载地址为http://kylin.apache.org/download/
软件包 | 说明 |
apache-kylin-1.5.3-src.tar.gz | 源码包 |
apache-kylin-1.5.3-bin.tar.gz | 可执行软件包,对应Hbase版本为Apache 0.98/0.99 |
apache-kylin-1.5.3-HBase1.x-bin.tar.gz | 可执行软件包,对应Hbase版本为Apache 1.x |
apache-kylin-1.5.3-cdh5.7-bin.tar.gz | 可执行软件包,对应CDH 5.7 |
1、搭建大数据平台环境,必备软件依赖为Zookeeper、Hadoop、Hive、Hbase。必须保证这些服务都是运行并且正常。
2、拷贝Kylin软件包到/opt/beh/core下并解压
$ mv apache-kylin-1.5.3-HBase1.x-bin.tar.gz /opt/beh/core
$ tar zxvf apache-kylin-1.5.3-HBase1.x-bin.tar.gz
$ ln -s apache-kylin-1.5.3-HBase1.x-bin kylin
3、配置/opt/beh/conf/beh_env添加如下环境变量并source使之生效。
$ export KYLIN_HOME=$BEH_HOME/core/kylin
4、检测kylin所需环境变量,若没有报错可继续。
$ cd $KYLIN_HOME
$ ./bin/check-env.sh
5、启动kylin服务
$ cd $KYLIN_HOME
$ ./bin/kylin.sh start
关闭服务如:./bin/kylin.sh stop
6、日志文件为/opt/beh/core/kylin/logs/kylin.log可以检测是否存在问题。
7、访问web端口http://192.168.5.143:7070/kylin/login
默认用户名/密码:ADMIN/KYLIN
2 测试过程
2.1 维度测试
测试所使用的宽表字段数为208个,数据条数约5000w条。
2.1.1 构建cube
2.1.1.1 指标
从三维测试到十五维,维度数持续增加,指标固定为以下三个字段
字段名 | 列名 |
出账费用(元) | ACCT_FEE |
月租费(元) | RENT_FEE |
非漫游通话时长(分钟) | NO_ROAM_CALL_DURA |
2.1.1.2 三维cube
字段名 | 列名 | Distinct(count) |
月份 | MONTH_ID | 1 |
省份 | PROV_ID | 2 |
地市 | AREA_ID | 35 |
2.1.1.3 四维cube
字段名 | 列名 | Distinct(count) |
月份 | MONTH_ID | 1 |
省份 | PROV_ID | 2 |
地市 | AREA_ID | 35 |
服务类型 | SERVICE_TYPE | 3 |
2.1.1.4 五维cube
字段名 | 列名 | Distinct(count) |
月份 | MONTH_ID | 1 |
省份 | PROV_ID | 2 |
地市 | AREA_ID | 35 |
服务类型 | SERVICE_TYPE | 3 |
付费类型 | PAY_MODE | 2 |
2.1.1.5 六维cube
字段名 | 列名 | Distinct(count) |
月份 | MONTH_ID | 1 |
省份 | PROV_ID | 2 |
地市 | AREA_ID | 35 |
服务类型 | SERVICE_TYPE | 3 |
付费类型 | PAY_MODE | 2 |
是否在网 | IS_INNET | 1 |
2.1.1.6 七维cube
字段名 | 列名 | Distinct(count) |
月份 | MONTH_ID | 1 |
省份 | PROV_ID | 2 |
地市 | AREA_ID | 35 |
服务类型 | SERVICE_TYPE | 3 |
付费类型 | PAY_MODE | 2 |
是否在网 | IS_INNET | 1 |
是否发展 | IS_DEV | 2 |
2.1.1.7 八维cube
字段名 | 列名 | Distinct(count) |
月份 | MONTH_ID | 1 |
省份 | PROV_ID | 2 |
地市 | AREA_ID | 35 |
服务类型 | SERVICE_TYPE | 3 |
付费类型 | PAY_MODE | 2 |
是否在网 | IS_INNET | 1 |
是否发展 | IS_DEV | 2 |
是否本期离网 | IS_BREAK | 1 |
2.1.1.8 九维cube
字段名 | 列名 | Distinct(count) |
月份 | MONTH_ID | 1 |
省份 | PROV_ID | 2 |
地市 | AREA_ID | 35 |
服务类型 | SERVICE_TYPE | 3 |
付费类型 | PAY_MODE | 2 |
是否在网 | IS_INNET | 1 |
是否发展 | IS_DEV | 2 |
是否本期离网 | IS_BREAK | 1 |
是否活跃 | IS_ACTIVE | 2 |
2.1.1.9 十维cube
字段名 | 列名 | Distinct(count) |
月份 | MONTH_ID | 1 |
省份 | PROV_ID | 2 |
地市 | AREA_ID | 35 |
服务类型 | SERVICE_TYPE | 3 |
付费类型 | PAY_MODE | 2 |
是否在网 | IS_INNET | 1 |
是否发展 | IS_DEV | 2 |
是否本期离网 | IS_BREAK | 1 |
是否活跃 | IS_ACTIVE | 2 |
是否极低使用量 | IS_LOWER_VALUE_USER | 2 |
2.1.1.10 十二维cube
字段名 | 列名 | Distinct(count) |
月份 | MONTH_ID | 1 |
省份 | PROV_ID | 2 |
地市 | AREA_ID | 35 |
服务类型 | SERVICE_TYPE | 3 |
付费类型 | PAY_MODE | 2 |
是否在网 | IS_INNET | 1 |
是否发展 | IS_DEV | 2 |
是否本期离网 | IS_BREAK | 1 |
是否活跃 | IS_ACTIVE | 2 |
是否极低使用量 | IS_LOWER_VALUE_USER | 2 |
套餐类型 | PRODUCT_BASE_CLASS | 19 |
套餐名称 | PRODUCT_BASE_CLASS_DESC | 19 |
2.1.1.11 十五维cube
字段名 | 列名 | Distinct(count) |
月份 | MONTH_ID | 1 |
省份 | PROV_ID | 2 |
地市 | AREA_ID | 35 |
服务类型 | SERVICE_TYPE | 3 |
付费类型 | PAY_MODE | 2 |
是否在网 | IS_INNET | 1 |
是否发展 | IS_DEV | 2 |
是否本期离网 | IS_BREAK | 1 |
是否活跃 | IS_ACTIVE | 2 |
是否极低使用量 | IS_LOWER_VALUE_USER | 2 |
套餐类型 | PRODUCT_BASE_CLASS | 19 |
套餐名称 | PRODUCT_BASE_CLASS_DESC | 19 |
产品分类 | PRODUCT_CLASS | 49 |
星座[原:套餐名称] | PRODUCT_CLASS_DESC | 154 |
用户状态 | USER_STATUS | 4 |
2.1.2 汇总cube
维度测试部分,我们选取的指标都是一致的,所有的维度对应字段distinct后的count值都较小,以下为创建成功后的cube数据汇总结果:
维度数 | Cube Duration(mins) | Hive Size(Bytes) | Cube Size(Bytes) | Cube Records |
3 | 3.77 | 1,479 | 5,617 | 35 |
4 | 4.5 | 13,323 | 9,953 | 583 |
5 | 4.98 | 33,451 | 26,268 | 1617 |
6 | 5.38 | 51,136 | 43,117 | 3235 |
7 | 7.7 | 172,541 | 145,966 | 9507 |
8 | 9.9 | 338,903 | 236,105 | 19015 |
9 | 11.92 | 1,109,773 | 895,912 | 56583 |
10 | 19.02 | 3,228,821 | 2,772,529 | 156927 |
12 | 75.87 | 66,343,681 | 57,891,724 | 3359007 |
15 | 79.95 | 528,668,938 | 459,107,973 | 28729023 |
从Cube的创建周期图可以很明显的看到,在维度数目较少的时候,创建cube花费的时间都较短,随着维度数目的增加,创建cube所花费的时间也越来越长,尤其是在第十维到十二维的时候,花费的时间陡然增加:
从Cube的资源消耗图也可以看出,不论是hive的size还是cube的size都是在维度数的增加而增加,同时Cube的records也是越来越多。
2.2 极限测试
2.2.1 测试一 最大化测试
2.2.1.1 Cube设计
通过将5000w数据的宽表各字段distinct后,选举了6个具有代表性的字段作为维度,其中用户ID字段为表中唯一值,也就是表的总记录数。
维度字段
字段名 | 列名 | Distinct(count) |
用户ID | SUBS_INSTANCE_ID | 54966176 |
客户标识 | CUST_ID | 39080419 |
手机品牌 | FACTORY_DESC | 2019 |
终端制式 | TERM_DESC | 39337 |
合约类型 | ACTIVITY_TYPE | 10 |
月份 | MONTH_ID | 1 |
指标字段
字段名 | 列名 | Distinct(count) |
使用流量(Mb) | USE_FLOW | 10945143 |
本地非漫游上网流量(Mb) | LOCAL_FLUX | 10046124 |
2.2.1.2 Cube构建
2.2.1.2.1 维度设计
选取了以下字段作为维度字段进行Cube的构建:
2.2.1.2.2 指标设计
选择SUM聚合运算对指标进行处理,如下:
2.2.1.3 构建结果
由于用户ID字段数值过大,导致cube无法成功构建:
2.2.1.3.1 构建cube的报错
经过多次测试,每次都是在第四步创建维度字典时失败,同时发现在第三步时候生成的数据为1.43GB,而之前进行21维测试时,选取的维度字段条数均很小,在第三步生成的数据仅仅只有18.74MB,相差甚大,具体对比如下:
2.2.1.3.2 错误日志
同时gc的日志中也发现时间过长
2.2.2 测试二 十万测试
2.2.2.1 Cube设计
选取distinct(count)=10w的字段进行维度构建:
字段名 | 列名 | Distinct(count) |
套餐名称 | PRODUCT_BASE_CLASS_DESC | 19 |
套餐类型 | PRODUCT_BASE_CLASS | 19 |
星座[原:套餐名称] | PRODUCT_CLASS_DESC | 154 |
产品分类 | PRODUCT_CLASS | 49 |
地市 | AREA_ID | 35 |
月份 | MONTH_ID | 1 |
省内漫游通话时长(分钟) | SN_ROAM_CALL_DURA | 99713 |
2.2.2.2 Cube构建
2.2.2.3 构建结果
成功构建出了cube
2.2.3 测试三 百万测试
2.2.3.1 Cube设计
选取了distinct(count)=150w的字段进行维度构建:
字段名 | 列名 | Distinct(count) |
套餐名称 | PRODUCT_BASE_CLASS_DESC | 19 |
套餐类型 | PRODUCT_BASE_CLASS | 19 |
星座[原:套餐名称] | PRODUCT_CLASS_DESC | 154 |
产品分类 | PRODUCT_CLASS | 49 |
地市 | AREA_ID | 35 |
月份 | MONTH_ID | 1 |
非漫游通话时长(分钟) | no_roam_out_call_dura | 1545306 |
2.2.3.2 Cube构建
维度设计
2.2.3.3 构建结果
构建cube时报错:
reduce内存不够,调整参数
参数调整后,resume该cube,构建成功:
2.3 分区测试
2.3.1 Cube设计
新增date_part分区字段,字段格式为yyyymmdd,并且插入了20160801 -20160805五个分区的数据,Cube维度设计如下表所示
字段名 | 列名 | Distinct(count) |
月份 | MONTH_ID | 1 |
省份 | PROV_ID | 2 |
地市 | AREA_ID | 35 |
服务类型 | SERVICE_TYPE | 3 |
付费类型 | PAY_MODE | 6 |
日期分区 | DATE_PART | 1 |
2.3.2 Cube构建
2.3.3 测试步骤
2.3.3.1 单分区结果表refresh测试
设计完cube后,分别build每个分区的cube。
生成了5张hbase表如下
执行了跨结果表sql查询,结果如下
所以kylin是支持跨结果表查询的。
每个分区对应一张hbase的结果表,可以对其中一个分区进行refresh操作,refresh 20160805账期的cube,会生成新的hbase表。
同时原20160805账期的hbase表依旧保存着:
2.3.3.2 多分区结果表merge测试
Merge以上5个分区的cube,生成的hbase结果表为一张表
同时原先在hbase中的各个分区结果表都已经被删除,因此也不再支持只refresh一个分区账期的数据,无法选择单独的分区账期进行refresh。
Ø 生成的结果表大小比较:
merge前五个hbase的结果表大小:
merge后一个hbase的结果表大小:
Merge前每个hbase结果表的大小均为26.6k,而merge之后合并成的一张结果表的大小为31.8k并非五张表的总和。
Ø 生成的结果表条数比较:
merge前单个hbase的结果表记录数:
1794条
Merge后的hbase的记录数:
2502条