0
4

1 回答 1

4

即使有状态函数,底层 Flink 作业的拓扑结构在作业启动时也是固定的。每个有状态的函数作业都使用或多或少像这样的作业图(入口各不相同,但其余的总是这样):

在此处输入图像描述

在这里,您可以看到所有加载的入口都成为 Flink 源操作符发出输入消息,路由器成为链接到这些源的平面图操作符。

充当路由器的平面图将输入消息转换为内部事件信封,它本质上只是将消息有效负载与其目标逻辑地址包装在一起。信封是流经流图的所有消息的在线数据类型。Stateful Functions 运行时以函数调度器运算符为中心,该运算符跨所有模块运行所有已加载函数的实例。

在路由器平面图操作符和函数调度器操作符之间是一个 keyBy 操作,它使用目标目的地id作为键对输入流进行重新分区。这种网络洗牌保证所有用于给定的消息id都发送到函数调度操作符的同一个实例。

收到后,函数调度程序从信封中提取目标函数地址,加载该函数实例,然后使用包装的输入(也在信封中)调用该函数。

函数调度器的不同实例如何相互发送消息?

这是通过将每个函数调度器与反馈运算符放在一起来完成的。所有传出消息都使用目标函数id作为键通过另一个网络洗牌。

此反馈运算符在作业图中创建一个循环或迭代。有状态函数在其消息传递模式中可以有循环或循环,并且不限于使用 DAG 处理数据。

反馈通道有检查点;在失败的情况下消息永远不会丢失。

有关这方面的更多信息,我推荐 Tzu-Li (Gordon) Tai 的 Flink Forward 演讲:Stateful Functions: Polyglot Event-Driven Functions for Stateful Distributed Applications。上图来自他的演讲。

于 2020-08-23T18:02:59.617 回答