Introduction
在本文我们首先聊聊系统提供的构建Kylin Cube的三种途径,以及其优缺点。后面的篇幅主要集中在集成到第三方调度平台的实现逻辑。
构建Cube的3种途径:
Kylin Web:

这是常用的一种方法,比较便捷、可视化。
需要强调的是,不管是哪种方式submit的build任务,都可通过Web监控。
命令行工具:

${cube}
cube名称
${startTime}
和 ${endTime}
构建的时间范围,应该是utc时间。
在Kylin服务器上用命令行工具时,不需要再进行进行权限认证。
RESTful API
主要分为两步:认证、提交构建cube任务。kylin使用basic authentication进行认证,在post请求上加上用于认证的 Authorization 头部:
POST http://localhost:7070/kylin/api/user/authentication
完成认证后就可以提交cube任务:
PUT http://localhost:7070/kylin/api/cubes/{cube_name}/rebuild
关于 put请求体的参数:
startTime
和endTime
应该是utc时间,时间戳格式。buildType
可以是BUILD
、MERGE
或REFRESH
。BUILD
用于构建一个新的segment,REFRESH
用于刷新一个已有的segment,MERGE
用于合并多个已有的segment生成一个较大的segment。
Postman简化了http请求调用方式,请求时的头部信息:

Body带上参数,指定build、refresh、merger,以及时间范围:

Why to do it ...
如果我们用上面的三种方式build,存在以下问题:
1、数据依赖
从数据架构的角度看,Kylin Data Source来源于数据仓库,这就会有数据依赖:只有数据仓库中的任务跑完后,才能跑Cube任务。显而易见,底层数据没有准备好,跑cube任务没有任何意义。
2、自动化调度
系统自带的构建工具,不管是web页面还是命令行,都需要手动操作。
如果简单的预测一个底层数据准备好的时间,然后在crontab定时build cube。这种方式虽然避免了繁琐的手动操作,但还存在数据依赖风险:不能严格保证底层数据准备完毕。
一般公司的调度平台都能配置任务依赖,调度触发也支持多种方式,比如时间触发、事件触发等,从任务统一调度的角度看,也需要把build cube集成到调度中心。
调度平台支持的任务类型也比较丰富,包括Hive、Spark、RDBMS导入Hive、Hive导出RDBMS、邮件任务、脚本任务等,而且易于扩展,增加Kylin Cube任务比较方便。
Getting ready ...
我们需要修改kylin代码、重新打包,从githup上clone kylin,然后切换到特定branch或tag,比如我们跑的是kylin-2.5.1版本。
每个公司的调度平台实现方式会有所不同,我们公司支持跑jar包,submit build cube的任务封装成jar包。

整个设计思想就是从元数据获取到调度cube所需参数,然后kylin执行完build任务后,再把任务执行的结果(成功、失败)回写到元数据库,并更新任务信息。
How to do it ...
1、调度cube任务的关键元数据配置:
{ "startTime":"2019-02-01", // 构建cube的数据起始时间
"endTime":"2019-02-02", // 构建cube的数据结束时间
"buildType":"BUILD", // 构建类型:BUILD|MERGE|REFRESH
"cube":"KYLIN_HIVE_METRICS_JOB_QA" } // CUBE名
2、submit cube
用户认证

解析请求Body信息
用RESTful API构建Cube时,请求Body是一个JSON格式数据,包含三个属性:startTime、endTime、buildType,只需要把元数据中的cube属性删除,startTime和endTime转换为时间戳。
提交构建cube任务

3、Kylin执行Cube任务时状态捕获
打开kylin CubeController类,该类是Restful API的入口,对每个
api都能找到对应的处理函数,比如build的请求:

在JobService类中增加job提交后记录日志的功能:

当任务执行成功或失败时,我们需要做不同处理,比如在对应元数
据中设置对应的任务成功、失败等,实现kylin真正的和调度平台的数据交互。

然后在ScheduleIntegratedService类中的onStatusChange方法实现不同状态的处理:

Dao层实现具体的和元数据交互,根据不同系统特点,做不同业务处理。
4、Kylin连接调度平台元数据
kylin.properties配置调度系统的元数据连接信息,这里以Mysql数据库为例:

KylinConfigBase类新增获取上述配置数据的方法:

How it works ...
1、元数据配置:
配置kylin连接调度平台中的信息,比如IP、端口号、用户名、密码等。kylin会把kylin.properties加载到系统变量。
2、submit cube
101行 - 105行是实现用户登录认证的函数,认证PATH:/kylin/api/user/authentication
109行对用户名和密码进行Basic编码,112行 - 117行设置Header信息,并用HttpURLConnection进行Http请求,返回的response判断请求认证是否成功。
93行 - 97行封装submit cube功能,cubeName是从元数据中解析出的cube字段;body是上面操作解析出的String对象。Build URL PATH:/kylin/api/cubes/{cubeName}/build
3、Kylin执行Cube任务时状态捕获
我们首先需要在kylin成功提交任务后,有个日志记录说明,跟踪CubeController中的buildCube方法后发现JobService中的submitJob方法是任务提交的方法。218行 - 223行是成功提交任务后回写日志的功能。
MapReduce引擎构建cube的实现类CubingJob,在job任务状态改变时,都会调用该类的onStatusChange函数,在ScheduleIntegratedService业务类中实现不同状态触发不同数据交互。
There's more ...
遗留的一些问题:
可以同时build同一时间段的segment,理论上是不能这样,偶尔会出现这样的情况
只能对MapReducer Build Job起作用,如果是Spark引擎构建就不起作用
build segment的开始时间和结束时间可以相同,也应该是不允许的
See also ...
用Api构建Cube:
http://kylin.apache.org/cn/docs/howto/howto_use_restapi.html
建立系统Cube章节,有shell 命令定期 build Cube的内容:
http://kylin.apache.org/cn/docs/tutorial/setup_systemcube.html




