Apache Kylin : Analytical Data Warehouse for Big Data
Welcome to Kylin Wiki.
一、为什么需要调度?
kylin在构建Cube的过程中,会产生很多的任务等待执行。为了协调这些任务的执行过程,能够高效合理的利用资源,就需要用到任务调度机制。
二、kylin有哪些任务调度器?
在目前的kylin版本中,共有3种任务调度器,它们的实现类分别是DefaultScheduler、DistributedScheduler、CuratorScheduler。用户可以通过配置参数kylin.job.scheduler.default为不同的值来选择使用哪种调度器,默认情况下kylin.job.scheduler.default=0,使用DefaultScheduler进行任务调度,配置为2时使用DistributedScheduler,配置为100时使用CuratorScheduler。
三、不同任务调度算法之间的区别是什么?
1、DefaultScheduler(默认配置)
DefaultScheduler是kylin最初使用的job调度方式,也是默认的调度实现,它的核心逻辑是初始化两个线程池,一个线程池ScheduledExecutorService用于抓取kylin中所有的job信息,另一个线程池JobRunner来执行具体的job。ScheduledExecutorService会定时抓取所有Job的状态信息,当Job的状态为Ready时,说明该Job可以被调度执行,就会将该Job交给JobRunner去执行。
DefaultScheduler所实现的调度是单机版的调度,即在同一份元数据下只能有一个Job server。当一个kylin server的kylin.server.mode=all或者job时,进程启动时会初始化DefaultScheduler,并对该job server加锁,该锁的实现类为ZookeeperJobLock,利用zookeeper的临时节点实现。一旦一个job server持有锁以后,在该job server进程结束之前,其他的job server都无法获取到锁。
2、DistributedScheduler
DistributedScheduler是美团贡献的分布式调度算法,从kylin 1.6.1版本开始支持。使用DistributedScheduler作为调度算法可以在同一份元数据下拥有多个kylin job server。
与DefaultScheduler相比,DistributedScheduler缩小了锁的粒度,从对整个job server加锁变成对segment加锁,实现类为ZookeeperDistributedLock,同样利用zookeeper的临时节点实现。
当一个segment构建任务被提交,任务被调度执行时会将JobId拼在zookeeper临时节点路径中,并对该节点加锁,当整个任务的最终状态变成SUCCEED,ERROR 和DISCARDED释放锁。
用户还可以在cube级别通过配置kylin.cube.schedule.assigned-servers来指定该cube的构建任务执行节点。
3、CuratorScheduler
CuratorScheduler是kyligence实现的一个基于curator的调度算法,从kylin3.0.0-alpha开始支持。
CuratorScheduler为主从模式,从所有job节点中选举出一个leader来进行任务调度,依赖curator的高级特性curator-recipes实现。Curator 有两种leader选举的实现,分别是LeaderSelector和LeaderLatch。前者是所有存活的客户端不间断的轮流做Leader,一个leader执行完takeLeaderShip方法即释放领导权。后者是一旦选举出Leader,除非有客户端挂掉重新触发选举,否则不会交出领导权。Kylin中使用LeaderSelector来进行leader选举。
Kylin中从LeaderSelectorListenerAdapter扩展实现了CuratorLeaderSelector来控制leader选举的处理逻辑,并重写其中的takeLeadership方法来实现任务调度。leaderSelector作为该类的核心成员变量在构造函数中被初始化。
当一个kylin job server启动时,就会从该job server初始化出一个jobClient,jobClient调用start()方法来启动,一旦启动,该jobClient即参与leader选举。同一元数据下的所有job server都会参与leader选举,同一时间只有一个job server成为leader,其他job server成为Participant。
成为leader的job节点会执行takeLeaderShip方法,这个方法调用DefaultScheduler的初始化方法,然后这个方法调用一个死循环,也就是说此节点将一直负责调度执行kylin任务,一旦出现问题则流程结束,defaultScheduler终止,该节点交出领导权,重新从所有job server中选取leader。