Flink(八)CEP
1.概述
所谓 CEP,其实就是“复杂事件处理(Complex Event Processing)”的缩写;而 Flink CEP,就是 Flink 实现的一个用于复杂事件处理的库(library)。那到底什么是“复杂事件处理”呢?就是可以在事件流里,检测到特定的事件组合并进行处理,比如说“连续登录失败”,或者“订单支付超时”等等
具体的处理过程是,把事件流中的一个个简单事件,通过一定的规则匹配组合起来,这就是“复杂事件”;然后基于这些满足规则的一组组复杂事件进行转换处理,得到想要的结果进行输出
总结起来,复杂事件处理(CEP)的流程可以分成三个步骤:
(1)定义一个匹配规则,匹配规则就是模式,主要由两部分组成,每个简单事件的特征 和 简单事件之间的组合关系
(2)将匹配规则应用到事件流上,检测满足规则的复杂事件
(3)对检测到的复杂事件进行处理,得到结果进行输出

CEP 主要用于实时流数据的分析处理。CEP 可以帮助在复杂的、看似不相关的事件流中找出那些有意义的事件组合,进而可以接近实时地进行分析判断、输出通知信息或报警。这在企业项目的风控管理、用户画像和运维监控中,都有非常重要的应用
-
风险控制
当一个用户行为符合了异常行为模式,比如短时间内频繁登录并失败、大量下单却不支付(刷单),就可以向用户发送通知信息,或是进行报警提示、由人工进一步判定用户是否有违规操作的嫌疑。这样就可以有效地控制用户个人和平台的风险 -
用户画像
利用 CEP 可以用预先定义好的规则,对用户的行为轨迹进行实时跟踪,从而检测出具有特定行为习惯的一些用户,做出相应的用户画像。基于用户画像可以进行精准营销,即对行为匹配预定义规则的用户实时发送相应的营销推广;这与目前很多企业所做的精准推荐原理是一样的 -
运维监控
对于企业服务的运维管理,可以利用 CEP 灵活配置多指标、多依赖来实现更复杂的监控模式
CEP 的应用场景非常丰富。很多大数据框架,如 Spark、Samza、Beam 等都提供了不同的CEP 解决方案,但没有专门的库(library)。而 Flink 提供了专门的 CEP 库用于复杂事件处理,可以说是目前 CEP 的最佳解决方案
2.快速入门
需要引入的依赖
<dependency>
<groupId>org.apache.flink</groupId>
<artifactId>flink-cep_${scala.binary.version}</artifactId>
<version>${flink.version}</version>
</dependency>
接下来我们考虑一个具体的需求:检测用户行为,如果连续三次登录失败,就输出报警信息。很显然,这是一个复杂事件的检测处理,我们可以使用 Flink CEP 来实现。我们首先定义数据的类型。这里的用户行为不再是之前的访问事件 Event 了,所以应该单独定义一个登录事件 POJO 类。具体实现如下:
public class LoginEvent {
// 用户id
public String userId;
// 用户ip地址
public String ipAddress;
// 用户登录成功与否
public Boolean eventType;
// 登录时间戳
public Long timestamp;
public LoginEvent() {
}
// 省略toString 有参构造
}
public class LoginDetectExample {
public static void main(String[] args) throws Exception {
// 创建一个表执行环境
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
StreamTableEnvironment tableEnv = StreamTableEnvironment.create(env);
env.setParallelism(1);
env.getConfig().setAutoWatermarkInterval(100); // 100毫秒生成一次水位线
// 1.用户登录事件
SingleOutputStreamOperator<LoginEvent> streamOperator = env.fromElements(
new LoginEvent("1", "192.168.10.1", false, 1000L),
new LoginEvent("2", "192.168.10.6", true, 2000L),
new LoginEvent("1", "192.168.10.1", false, 5000L),
new LoginEvent("2", "192.168.10.6", false, 5000L),
new LoginEvent("1", "192.168.10.1", false, 4000L)
).assignTimestampsAndWatermarks(WatermarkStrategy
.<LoginEvent>forBoundedOutOfOrderness(Duration.ofSeconds(2)) // 延迟2秒保证数据正确
.withTimestampAssigner(new SerializableTimestampAssigner<LoginEvent>() {
@Override // 时间戳的提取器
public long extractTimestamp(LoginEvent event, long l) {
return event.timestamp;
}
})
);
// 2.定义模式
// 2.1 模式的第一个事件是用户登陆失败
Pattern<LoginEvent, LoginEvent> loginEventPattern = Pattern.<LoginEvent>begin("first-false")
.where(new SimpleCondition<LoginEvent>() {
@Override
public boolean filter(LoginEvent loginEvent) throws Exception {
return !loginEvent.eventType; // 类型为false的则代表登陆失败
}
}) // next衔接模式的第二个事件
.next("second-false")
.where(new SimpleCondition<LoginEvent>() {
@Override
public boolean filter(LoginEvent loginEvent) throws Exception {
return !loginEvent.eventType;
}
}) // 以后的每个事件都用next衔接即可
.next("third-false")
.where(new SimpleCondition<LoginEvent>() {
@Override
public boolean filter(LoginEvent loginEvent) throws Exception {
return !loginEvent.eventType;
}
});
// 3.将模式应用到数据流,检测复杂事件
PatternStream<LoginEvent> patternStream = CEP.pattern(streamOperator.keyBy(event -> event.userId), loginEventPattern);
// 4.提取复杂事件,进行处理 select类似于map 只不过我们处理的是一组事件
SingleOutputStreamOperator<String> warningOut = patternStream.select(new PatternSelectFunction<LoginEvent, String>() {
@Override // 这里是一个map map的key就是我们定义的事件名称,value对应的事件列表,我们这里列表里只有一个事件,为什么是列表,因为我们定义的一个事件,它可能会重复发生
public String select(Map<String, List<LoginEvent>> map) throws Exception {
// 提取三次事件
LoginEvent firstFailEvent = map.get("first-false").get(0);
LoginEvent secondFailEvent = map.get(

本文详细介绍了Flink的复杂事件处理库CEP,包括CEP的基本概念、快速入门示例、模式API的使用,如个体模式、组合模式、匹配后跳过策略等,并展示了如何处理匹配事件和超时事件,阐述了CEP在实时流数据分析中的应用和重要性。
CEP&spm=1001.2101.3001.5002&articleId=125497083&d=1&t=3&u=d9e351998dc4419e8f9f9afd2403977a)
2856

被折叠的 条评论
为什么被折叠?



