Flink源码剖析:flink-cep 自带测试用例

本文深入探讨了Flink源码中的CEP模块,通过运行并分析测试用例如testSimplePatternCEP、testSimpleKeyedPatternCEP等,揭示了Flink cep在处理时间序列模式匹配的能力,包括事件时间和处理时间场景,以及不同key的划分。同时,展示了如何处理超时事件和使用过滤器功能。
摘要由CSDN通过智能技术生成

本文主要针对 Flink 源码中 flink-cep 模块,带大家跑一下其中的测试类 CEPITCase.java ,可以直观的了解到 flink cep 的功能。
为了方便分析,对源码中的示例会有些许改动,并把代码粘贴在了文中。


1. testSimplePatternCEP

public class CEPITCase extends AbstractTestBase{
   

    /**
	 * Checks that a certain event sequence is recognized.
	 * 全局匹配一组先后发生的事件序列
	 */
	@Test
	public void testSimplePatternCEP() throws Exception {
   
		StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

		DataStream<Event> input = env.fromElements(
			new Event(1, "barfoo", 1.0),
			new Event(2, "start", 2.0),
			new Event(3, "foobar", 3.0),
			new SubEvent(4, "foo", 4.0, 1.0),
			new Event(5, "middle", 5.0),
			new SubEvent(6, "middle", 6.0, 2.0),
			new SubEvent(7, "bar", 3.0, 3.0),
			new Event(42, "42", 42.0),
			new Event(8, "end", 1.0)
		);

		// Pattern 组
		Pattern<Event, ?> pattern = Pattern.<Event>begin("start").where(new SimpleCondition<Event>() {
   

			@Override
			public boolean filter(Event value) throws Exception {
   
				// start Pattern
				System.out.println("testSimplePatternCEP start -> " + value + ", " + value.getName().equals("start"));
				return value.getName().equals("start");
			}
		})
			// 1. 前一个模式
			// 2. 创建一个新的模式
			// 3. 模式名
			// 4. where 指定模式内容
			.followedByAny("middle").subtype(SubEvent.class).where(
				new SimpleCondition<SubEvent>() {
   

					@Override
					public boolean filter(SubEvent value) throws Exception {
   
						// middle Pattern
						// 5. 核心处理逻辑
						System.out.println("testSimplePatternCEP middle -> " + value + ", " + value.getName().equals(
							"middle"));
						return value.getName().equals("middle");
					}
				}
			)
			.followedByAny("end").where(new SimpleCondition<Event>() {
   

				@Override
				public boolean filter(Event value) throws Exception {
   
					// end Pattern
					System.out.println("testSimplePatternCEP end -> " + value + ", " + value.getName().equals("end"));
					return value.getName().equals("end");
				}
			});

		// CEP 匹配
		PatternStream<Event> patternStream = CEP.pattern(input, pattern);

		// 经过 CEP 匹配之后的输出流
		DataStream<String> result = patternStream.flatSelect((p, o) -> {
   
			StringBuilder builder = new StringBuilder();

			builder.append(p.get("start").get(0).getId()).append(",")
				.append(p.get("middle").get(0).getId()).append(",")
				.append(p.get("end").get(0).getId());

			o.collect(builder.toString());
			System.out.println("testSimplePatternCEP -> " + builder.toString());
		}, Types.STRING);

		List<String> resultList = new ArrayList<>();

		DataStreamUtils.collect(result).forEachRemaining(resultList::add);

		// 根据设置的 Pattern,返回 id 列表 2,6,8
		assertEquals(Arrays.asList("2,6,8"), resultList);
	}
	
}

输出结果,匹配出 <2,6,8> 序列:

testSimplePatternCEP start -> Event(1, barfoo, 1.0), false
testSimplePatternCEP start -> Event(2, start, 2.0), true
testSimplePatternCEP start -> Event(3, foobar, 3.0), false
testSimplePatternCEP middle -> SubEvent(4, foo, 4.0, 1.0), false
testSimplePatternCEP start -> SubEvent(4, foo, 4.0, 1.0), false
testSimplePatternCEP start -> Event(5, middle, 5.0), false
testSimplePatternCEP middle -> SubEvent(6, middle, 6.0, 2.0), true
testSimplePatternCEP start -> SubEvent(6, middle, 6.0, 2.0), false
testSimplePatternCEP end -> SubEvent(7, bar, 3.0, 3.0), false
testSimplePatternCEP middle -> SubEvent(7, bar, 3.0, 3.0), false
testSimplePatternCEP start -> SubEvent(7, bar, 3.0, 3.0), false
testSimplePatternCEP end -> Event(42, 42, 42.0), false
testSimplePatternCEP start -> Event(42, 42, 42.0), false
testSimplePatternCEP end -> Event(8, end, 1.0), true
testSimplePatternCEP start -> Event(8, end, 1.0), false
testSimplePatternCEP -> 2,6,8



2. testSimpleKeyedPatternCEP

public class CEPITCase extends AbstractTestBase {
   
        /**
    	 * 先按照 id 分组,再去匹配各自的 Pattern
    	 */
    	@Test
    	public void testSimpleKeyedPatternCEP() throws Exception {
   
    		StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
    		env.setParallelism(2);
    
    		DataStream<Event> input = env.fromElements(
    			new Event(1, "barfoo", 1.0),
    			new Event(2, "start", 2.0),
    			new Event(3, "start", 2.1),
    			new Event(3, "foobar", 3.0),
    			new SubEvent(4, "foo", 4.0, 1.0),
    			new SubEvent(3, "middle", 3.2, 1.0),
    			new Event(42, "start", 3.1),
    			new SubEvent(42, "middle", 3.3, 1.2),
    			new Event(5, "middle", 5.0),
    			new SubEvent(2, "middle", 6.0, 2.0),
    			new SubEvent(7, "bar", 3.0, 3.0),
    			new Event(42, "42", 42.0),
    			new Event(3, "end", 2.0),
    			new Event(2, "end", 1.0),
    			new Event(42, "end", 42.0)
    		).keyBy(new KeySelector<Event, Integer>() {
   
    
    			@Override
    			public Integer getKey(Event value) throws Exception {
   
    				return value.getId();
    			}
    		});
    
    		Pattern<Event, ?> pattern = Pattern.<Event>begin("start").where(new SimpleCondition<Event>() {
   
    
    			@Override
    			public boolean filter(Event value) throws Exception {
   
    				System.out.println("testSimpleKeyedPatternCEP start -> " + value + ", " + value.getName().equals(
    					"start"));
    				return value.getName().equals("start");
    			}
    		})
    			.followedByAny("middle").subtype(SubEvent.class).where(
    				new SimpleCondition<SubEvent>() {
   
    
    					@Override
    					public boolean filter(SubEvent value) throws Exception {
   
    						System.out.println("testSimpleKeyedPatternCEP middle -> " + value + ", " + value.getName().equals("middle"));
    						return value.getName().equals("middle");
    					}
    				}
    			)
    			.followedByAny("end").where(new SimpleCondition<Event>() {
   
    
    				@Override
    				public boolean filter(Event value) throws Exception {
   
    					System.out.println("testSimpleKeyedPatternCEP end -> " + value + ", " + value.getName().equals(
    						"end"));
    					return value.getName().equals("end");
    				}
    			});
    
    		// 处理同一个 input 中的不同 event
    		DataStream<String> result = CEP.pattern(input, pattern).select(p -> {
   
    			StringBuilder builder = new StringBuilder();
    
    			builder.append(p.get("start").get(0).getId()).append
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值