我写了一个使用 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 })
您可以将我的用例视为基于缓存的重复数据删除,因此我希望所有并行任务都引用单个缓存对象
将 Guava 缓存与 Flink 一起使用通常是一种反模式。并不是说它不能工作,但可能有一个更简单、更具可扩展性的解决方案。
使用Flink 以完全可扩展、高性能的方式进行重复数据删除的标准方法是按某个键(使用 keyBy(对流进行分区,然后使用键化状态来记住已经看到的键。Flink 的密钥状态由 Flink 管理,使其具有容错性和可重新扩展性,同时保持本地状态。Flink 的键化状态是一个分片键/值存储,每个实例处理键空间某些部分的所有事件。您可以保证,对于每个密钥,同一密钥的所有事件都将由同一实例处理 - 这就是为什么这适用于重复数据删除的原因。
如果您需要所有并行实例都具有某些(可能正在演变的(数据集的完整副本,这就是广播状态的用途。
Flink 任务在多 JVM 或机器上运行,所以问题是如何在 JVM 之间共享对象。
通常,您可以通过RPC(通过tcp(或rest(通过http(调用从远程JVM获取对象。
或者,您可以序列化对象并像 reids 一样将它们存储到数据库中,然后从数据库中读取并反序列化为对象。
在 Flink 中,有一种更优雅的方式来实现这一点,你可以将对象存储在状态中,broadcast_state可能适合你。
引入广播状态是为了支持需要将来自一个流的某些数据广播到所有下游任务的用例
希望这有帮助。