flink cep 原理分析2(源码分析)

本文深入分析了 Flink CEP 的源码,探讨了事件和事件间的关联存储、Computation State 实现、事件处理流程以及版本管理。通过示例展示了缓冲区和状态在不同阶段的数据变化,揭示了Flink如何根据状态和事件生成匹配结果。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

flink cep 源码分析

1 前文介绍

前文中我们已经介绍啦关于cep的原理和缓存以及数据结构
https://blog.youkuaiyun.com/u013052725/article/details/100631259
接着我们看一看如何flink当中是如何实现的。其中cep版本是1.6.0。

2 首先我们思考四个问题:

a)事件和事件间的关联以及版本是如何在flink当中存储的。
b)Computation state 在flink 中是如何实现的
c)事件到来是如何根据Computation state 来计算有哪些边(take,process,ignore) ,以及如何更新Computation state
d)事件间的版本号如何生成
e)如何根据缓存数据以及版本号进行回溯输出结果

3 源码分析

a)我们先看看flink中 shared version match buffer 是如何实现的。
flink中实现缓存的实现:SharedBuffer类

SharedBuffer类中有三个存储数据的结构如下:
注:其中MapState 是flink中的状态我们可以理解为就是一个map,不过其数据可能存储在内存也可能持久化在磁盘上,详细说明看官网:
https://ci.apache.org/projects/flink/flink-docs-release-1.9/zh/dev/stream/state/state.html

	/** The buffer holding the unique events seen so far. */
	private MapState<EventId, Lockable<V>> eventsBuffer;

	/** The number of events seen so far in the stream per timestamp. */
	private MapState<Long, Integer> eventsCount;
	private MapState<NodeId, Lockable<SharedBufferNode>> entries;

EventId:每个事件会对应一个id
NodeId:包括EventId和事件所在state的名字
SharedBufferNode:存放一个节点所对应的边,可能有多条,以集合形式存在,其中每条边有版本号和target节点
eventsBuffer:key是EventId value是对应的值,存储所以匹配到的事件的id和对应的value值,用于输出的时候根据id取得数据。
eventsCount:key是事件的时间戳,value是这个事件在缓存中的数量
entries:key是NodeId 是事件在该缓存中的一个标志,value 是SharedBufferNode 存放这个节点所对应的各个版本的前置节点。匹配到的事件会存放在这个缓存当中,并且保存事件间的关系和版本号。匹配过程中主要使用的就是这个版本。

b)Computation state 在flink中的数据结构

Computation state 的数量代表啦当前run的数量每个 Computation state就是这个run的当前状态

// pointer to the NFA currentStateName of the computation
	private final String currentStateName;

	// The current version of the currentStateName to discriminate the valid pattern paths in the SharedBuffer
	private final DeweyNumber version;

	// Timestamp of the first element in the pattern
	private final long startTimestamp;

	@Nullable
	private final NodeId previousBufferEntry;

	@Nullable
	private final EventId startEventID;

currentStateName:描述当前run所在的state。可以根据state取得当前 state的事件迁移条件来判断事件的迁移情况。
version:当前state所对应的版本号。可以用于下个state版本号的计算和终止时回溯事件
startTimestamp:事件开始事件,用于判断是否超时
startEventID:开始事件id
previousBufferEntry:当前run的最后事件节点 下一个事件到达如果take会作为新的最后节点。新节点指向之前的节点。

c)事件到来的处理流程

如下方法doProcess 事件到达的处理流程

	private Collection<Map<String, List<T>>> doProcess(
			final SharedBuffer<T> sharedBuffer,
			final NFAState nfaState,
			final EventWrapper event,
			final AfterMatchSkipStrategy afterMatchSkipStrategy) throws Exception {
		//需要匹配的ComputationState列表
		final PriorityQueue<ComputationState> newPartialMatches = new PriorityQueue<>(NFAState.COMPUTATION_STATE_COMPARATOR);
		//匹配完成的ComputationState列表
		final PriorityQueue<ComputationState> potentialMatches = new PriorityQueue<>(NFAState.COMPUTATION_STATE_COMPARATOR);

		//迭代当前所有需要匹配的ComputationState
		for (ComputationState computationState : nfaState.getPartialMatches()) {
			//根据当前computationState和事件计算出下一个或者多个ComputationState,并且存储匹配到事件到sharebuffer中,这个方法很重要下面讲解
			final Collection<ComputationState> newComputationStates = computeNextStates(
				sharedBuffer,
				computationState,
				event,
				event.getTimestamp());

			if (newComputationStates.size() != 1) {
				nfaState.setStateChanged();
			} else if (!newComputationStates.iterator().next().equals(computationState)) {
				nfaState.setStateChanged();
			}

			//delay adding new computation states in case a stop state is reached and we discard the path.
			final Collection<ComputationState> statesToRetain = new ArrayList<>();
			//if stop state reached in this path
			boolean shouldDiscardPath = false;
			//遍历添加到添加到对应的列表中
			for (final ComputationState newComputationState : newComputationStates) {

				if (isFinalState(newComputationState)) {
					potentialMatches.add(newComputationState);
				} else if (isStopState(newComputationState)) {
					//reached stop state. release entry for the
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值