在flink数据流中,假设一个上游操作符托管在machine/task manager上 m
,上游操作员如何知道机器(任务管理器) m’
在其上承载下游运算符。在jobmanager对作业子/任务(操作符)的初始调度期间,是否在下游/上游操作符之间建立了这样的数据流路径,并且在应用程序生命周期内,这样的数据流路径是固定的?
一般来说,考虑支持动态消息传递、数据流不是固定的或预定义的flink有状态函数,并给定一个带有键的函数 k
需要用键向另一个函数发送消息/事件 k’
你将如何运作 k
查找函数的地址 k’
为了传达信息?flink运行时是否在某些分布式数据结构(如microsoft orleans中的dht)中保留了关键机Map,并且每次调用函数都涉及对此类数据结构的访问?
请注意,我来自spark的背景,在这里给定rdd/批处理模型,作业图任务是连续执行的(在洗牌边界处断开),每个洗牌子任务都被指示持有该子任务应该拉/处理的密钥子集的机器…。
谢谢您。
1条答案
按热度按时间ozxc1zmp1#
即使使用有状态函数,底层flink作业的拓扑在作业启动时也是固定的。每个有状态函数作业都或多或少地使用类似于此的作业图(入口不同,但其余的总是这样):
在这里,您可以看到所有加载的入口都成为发射输入消息的flink源操作符,而路由器成为链接到这些源的flatmap操作符。
作为路由器的flatmaps将输入消息转换为内部事件封套,而内部事件封套实质上只是用消息的目标逻辑地址 Package 消息负载。信封是流经流图的所有消息的在线数据类型。有状态函数运行时以函数分派器操作符为中心,它跨所有模块运行所有加载函数的示例。
在router flatmap操作符和function dispatcher操作符之间是一个keyby操作,它使用目标目的地重新划分输入流
id
作为关键。这种网络洗牌可以保证所有的消息都是针对一个给定的id
发送到函数分派操作符的同一示例。收到后,函数分派器从信封中提取目标函数地址,加载该函数示例,然后使用 Package 的输入(也在信封中)调用函数。
函数分派器的不同示例如何相互发送消息?
这是通过将每个函数调度器与一个反馈操作符放在一起实现的。所有传出的消息都使用target函数通过另一个网络洗牌
id
作为关键。此反馈操作符在作业图中创建循环或迭代。有状态函数在其消息传递模式中可以有循环,也可以有循环,并且不限于使用dag处理数据。
反馈通道被检查;在失败的情况下消息永远不会丢失。
关于这方面的更多信息,我推荐这篇由Tzi li(gordon)tai撰写的flink forward演讲:有状态函数:有状态分布式应用程序的多时隙事件驱动函数。上面的数字来自他的谈话。