科技排头@高级应用模式第二辑:应用模式的动态更新,Flink

在本系列的第一篇文章中 , 我们对欺诈检测引擎的目标和所需功能给出了高层次的描述 。 我们还解释了如何让ApacheFlink中的数据分区基于可修改的规则来定制 , 替代使用硬编码的KeysExtractor实现 。
我们特意略过了关于如何初始化应用的规则 , 以及在运行时有哪些方法来更新这些规则的细节内容 。 在这篇文章中我们将具体介绍这些细节 。 你将学习如何将第一部分中描述的数据分区方法与动态配置结合起来使用 。 只要共同使用这两种模式 , 调整很多业务逻辑时就不用再重新编译代码和重新部署Flink作业了 。
规则广播
首先我们来看一下先前定义的数据处理管道:
DataStream<Alert>alerts=transactions.process(newDynamicKeyFunction()).keyBy((keyed)->keyed.getKey());.process(newDynamicAlertFunction())DynamicKeyFunction提供动态数据分区 , 而DynamicAlertFunction负责执行处理事务的主要逻辑 , 并根据已定义的规则发送警报消息 。
本系列的第一篇文章简化了用例 , 并假定应用的规则集已预先初始化 , 可以通过DynamicKeyFunction中的List访问 。
publicclassDynamicKeyFunctionextendsProcessFunction<Transaction,Keyed<Transaction,String,Integer>>{/*Simplified*/List<Rule>rules=/*Rulesthatareinitializedsomehow.*/;...}显然 , 在初始化阶段就可以直接在Flink作业的代码内部向这个列表添加规则(创建一个List对象 , 使用它的add方法) 。 这样做的主要缺点是每次修改规则后都需要重新编译作业 。 在现实的欺诈检测系统中规则会经常更改 , 因此从业务和运营角度来看 , 这种方法是不可接受的 。 我们需要另一种方式 。
接下来是在上篇文章中引入的规则定义示例:
科技排头@高级应用模式第二辑:应用模式的动态更新,Flink
文章图片
图1:规则定义
【科技排头@高级应用模式第二辑:应用模式的动态更新,Flink】上一篇文章提到 , DynamicKeyFunction使用groupingKeyNames来提取消息键 。 该规则第二部分中的参数由DynamicAlertFunction使用:它们定义所执行操作的实际逻辑及其参数(例如警报触发阈值) 。 这意味着在DynamicKeyFunction和DynamicAlertFunction中必须存在相同的规则 。 为了获得这个结果 , 我们将使用ApacheFlink的数据分发广播机制 。
下图展示了我们正在构建系统的最终作业图:
科技排头@高级应用模式第二辑:应用模式的动态更新,Flink
文章图片
图2:欺诈检测Flink作业的作业图
事务处理管道的主要模块有:
事务源(TransactionSource) , 它并行消费来自Kafka分区的事务消息 。 动态键函数(DynamicKeyFunction) , 使用一个动态键执行数据强化(enrichment) 。 后续的keyBy对这个动态键进行哈希处理 , 并在随后的运算符的所有并行实例之间对数据进行分区操作 。 动态警报函数(DynamicAlertFunction) , 可生成一个数据窗口并基于该窗口创建警报 。ApacheFlink内部的数据交换
上面的作业图还指出了运算符之间的各种数据交换模式 。 为了解广播模式的工作机制 , 我们先走一小段弯路 , 讨论ApacheFlink的分布式运行时中存在哪些消息传播方法 。
事务源之后的FORWARD连接意味着事务源运算符的一个并行实例消费的所有数据 , 都将精确传输到后续DynamicKeyFunction运算符的一个实例上 。 它还指出两个连接的运算符(在上述情况下为12)并行度相同 。 此通信模式如图3所示 。 橙色圆圈表示事务 , 虚线矩形表示相联运算符的并行实例 。
科技排头@高级应用模式第二辑:应用模式的动态更新,Flink
文章图片
图3:跨运算符实例传递的FORWARD消息


推荐阅读