Kylin的广播机制在整个Kylin集群中作用非常重大,各个节点之间的数据同步均是通过广播机制进行。
1、Project/Model/Cube的元数据信息变化,由Broadcaster通过api的形式广播通知其他节点;
2、build完成后触发auto merge等。
广播机制大致流程:
- 1、注册事件监听器:
Tomcat启动后执行相关类的afterPropertiesSet方法,注册相关事件到Broadcaster中的listenerMap和staticListenerMap 两个容器中。
其中listenerMap存放普通的监听事件实体类型及其对应的listener,
staticListenerMap存放静态的监听事件实体类型和其listener;
(文中会具体将何时如何存放)
listenerMap和staticListenMap的key均为实体类型,value是具体的监听器List:
//listenerMap和staticListenMap内容示例
<"execute",list(new JobSyncListener())>
<"execute_output",list(new JobOutputSyncListener())>
<"all",list(new JobSyncListener(),new JobOutputSyncListener())>
<"project_schema",,list(new JobSyncListener(),new <"project_data",,list(new JobSyncListener(),new JobOutputSyncListener())>
<"project_acl",,list(new JobSyncListener(),new JobOutputSyncListener())>
.....
所有注册listenerMap监听器的代码:
所有注册staticListenMap监听器的代码:
上面两图中的这些类通常均为单例类型,在第一次实例化的时候执行注册相关事件监听器,有的是被其他类的afterPropertiesSet触发,有的则是从其他方法触发,总之均是在实例化的时候注册且只初始化一次。
//以execute、execute_output相关事体的监听注册为例
JobService.afterPropertiesSet()——》scheduler.init——》ExecutableManager.getInstance——》ExecutableDao.getInstance——》ExecutableDao构造方法——》ExecutableDao的构造方法会注册execute、execute_output等实体。
//
- 2、事件放入事件队列
可以触发事件的地方有很多,比如project/cube/mode update ,cube build 等。
他们最终都是在持久化的时候将相关事件放入事件队列(broadcastEvents),
调用方法栈:CachedCrudAssist.save——》SingleValueCache.put——》Broadcaster.announce——》存入待处理的事件队列(broadcastEvents)中。
- 3、触发事件队列
Broadcaster第一次被实例化时(只会被实例化一次)构造方法中会启动一个后台线程一直轮训,
依次从事件队列(broadcastEvents)中取出事件并执行相关方法(实际就是restfull api调用)
Broadcaster私有构造方法前半部分:
Broadcaster私有构造方法后半部分:
Restclient.wipeCache方法:
4、目的节点执行
实际调用的是目的节点CacheController的如下两个方法:
最终均调用CacheService.notifyMetadataChange方法:
继续向下调用,true表示需要执行静态staticListenerMap:
接下来就是去执行各个注册在staticListenerMap和listenerMap中相关具体方法。