如何将Flink作业与Guava缓存并行化?

时间:2019-03-26 18:27:12

标签: caching parallel-processing guava apache-flink flink-streaming

我写了一个使用Guava缓存的Flink作业。缓存对象是在main()函数中调用的run()函数中创建并使用的。

类似于:

main() {
   run(some,params)
}

run() {
   //create and use Guava cache object here
}

如果我以某种程度的并行度运行此Flink作业,那么所有并行任务会使用相同的缓存对象吗?如果没有,如何使它们全部使用单个缓存?

缓存在流的process()函数内部使用。就像

incoming_stream.process(new ProcessFunction() { //Use Guava Cache here })  

您可以将我的用例视为基于缓存的重复数据删除,因此我希望所有并行任务都引用单个缓存对象

2 个答案:

答案 0 :(得分:1)

在Flink中使用Guava缓存通常是一种反模式。并不是说它无法正常工作,而是可能存在一个更简单,可扩展性更高的解决方案。

使用Flink以完全可扩展的高性能方式进行重复数据删除的标准方法是按某个键对流进行分区(使用keyBy),然后使用键控状态来记住已看到的键。 Flink的键控状态由Flink管理,以使其容错和可伸缩,同时又保持其本地状态。 Flink的键控状态是分片的键/值存储,每个实例处理键空间的某些部分的所有事件。您可以确保对于每个键,同一键的所有事件都将由同一实例处理-这就是为什么此方法可很好地用于重复数据删除。

如果您需要所有并行实例都具有某些(可能正在发展)数据集的完整副本,那么这就是广播状态。

答案 1 :(得分:0)

Flink任务在多个JVM或机器上运行,因此问题在于如何在JVM之间共享对象。

通常,您可以通过RPC(通过tcp)或rest(通过http)调用从远程JVM获取对象。

或者,您可以序列化对象并将其像reids一样存储到数据库,然后从数据库中读取并反序列化为对象。

在Flink中,有一种更优雅的方法可以实现此目的,您可以将对象存储在state中,而broadcast_state可能适合您。

引入了广播状态以支持用例,其中需要将来自一个流的某些数据广播到所有下游任务

希望这会有所帮助。