ACTIVE—— IMMUTABLE ——REMOTE_PERSISTED——Ready
一、Active
每个segment创建的时候初始为Active状态,只有active状态的segment可以消费数据,由kylin receiver负责创建Active的segment,分别?如下两处触发:
1.1、启动Receiver时启动消费服务:
参见代码StreamingServer.start——》addToReplicaSet——》startConsumers——》startConsumer——》StreamingConsumerChannel.start——》run()——》StreamingSegmentManger.addEvent——》createSegment;
1.2、master enable cube时启动相应的receiver消费服务:
参见代码:CubeController.enableCube——》CubeService.enableCube——》Coordinator.assignCube——》doAssignCube——》assignCubeToReplicaSet——》assignToReceiver——》HttpReceiverAdminClient.assign——http调用——》AdminController(reciver).assign——》StreamingServer.startConsumers——》StreamingConsumerChannel.start——》run()——》StreamingSegmentManger.addEvent——》createSegment
二、Immutable
immutable状态由active的segment转换而来,变为immutable状态的segment不在接受消费新的数据。此状态主要通过如下两种方式触发而来:
2.1 通过消费每条kafka中的数据时判断:
通过每次消费一条kafka的新数据时且需要创建新的segment时则同时判断一次当前处于active的segment是否具备转换成immutable状态的条件(达到cubeDuration或者maxCubeDuration时间),在此时做状态变更。
参见代码:StreamingSegmentManager.addEvent——》findSegmentsToBeImmutable——》convertImmutable(list)——》convertImmutable(segment):从内存activeSegments中移除此segment、StreamingSegmentState.immutable(持久化此segment到磁盘、修改内存状态为immutable、修改磁盘此segment状态为immutable)、在内存immutableSegments放入此segment;
2.2 通过界面重新调整此cube的assignment:
将preAssignment(没有在new assignment中的replicaset)中的receiver的segment由active变为immutable。具体代码参见 Kylin Reassign 流程
三、REMOTE PERSISTED
此状态通过receiver启动的一个后台线程每60s轮训 Immutable的segment,将满足条件的开始上传(receiver leader && FULL_BUILD_POLICY)或者删除(purge policy),上传完成的变成REMOTE PERSISTED状态:
StreamingReceiver.main——》start——》startStreamingServer——》StreamingServer.start——》startSegmentStateChecker——》handleImmutableCubeSegments:将分为两种情况:
Case1: 上传到HDFS
此cube的的RetentionPolicyInfo为FULL_BUILD_POLICY且此receiver是此replicaset的leader,则调用sendSegmentsToFullBuild.HDFS存储路径为:
H
d
f
s
W
o
r
k
D
i
r
/
s
t
r
e
a
m
/
{HdfsWorkDir}/stream/
HdfsWorkDir/stream/{cubeName}/
s
e
g
m
e
n
t
N
a
m
e
/
{segmentName}/
segmentName/{replicaSetID}
StreamingServer. handleImmutableCubeSegments——》 sendSegmentsToFullBuild:
1、通过多线程方式将满足条件的segments本地数据上传到hdfs:参见代码new SegmentHDFSFlusher ;
某个segment上传完成后,在进行后续操作:
2、在zk中创建此segment此replisetId的remote store节点,供第4步coordinator寻找合适的segment去提交build(此segment的所有replicaset均上传完成后即在zk上创建remote store节后才可以进行真正build)【/kylin/KYLIN_PROD:kylin_metadata/stream/cubes/CubeName/build_state/SegnemtName/replica_sets/replica set id】,参见代码StreamMetadataStore.addCompleteReplicaSetForSegmentBuild;
3、在zk中保存此segment的checkpoint【 /kylin/KYLIN_PROD:kylin_metadata/stream/cubes/Cube_Name/source_checkpoint/SegmentName/replica set id (get内容为checkpoint)】),参见代码StreamMetadataStore.saveSourceCheckpoint ;
4、触发一次此cube提交build的检查:参见代码HttpCoordinatorClient.segmentRemoteStoreComplete——》StreamingCoordinatorController.segmentRemoteStoreComplete(http coordinator leader)——》StreamingCoordinatorService.onSegmentRemoteStoreComplete——》Coordinator.segmentRemoteStoreComplete——》tryFindAndBuildSegment(触发此cube一次找满足条件的rempote_persisted进行build job)——》findSegmentsCanBuild(即上述第2步中在zk中保存的节点(此segment的所有replicaset均完成上传)且此segment之前还没有被提交build并且没有达到最大并发build数)——》tryFindAndBuildSegment——》triggerSegmentBuild(add new segment in hbase、update zk 此segment buildstate并更新job id【get /kylin/BIGDATA_KYLIN:kylin_meadata_test/stream/cubes/new_task_snapshot_cube_clone3/build_state/20191022121000_20191022122000】、add build job in memory=jobStatusChecker、submit the job to run=hbase);
5、变更状态为remote_persisted,将此receiver上此segment的本地数据的状态和内存中的状态变更为remote_persisted
参见代码:StreamingCubeSegment.saveState——》ColumnarSegmentStore.setSegmentState|
四、Ready
Build job运行完成后并将数据入hbase后,segment变更为ready.