我有一个用例,其中 apache flink 进程必须集成来自多个源的近乎实时的数据流(事件),但由于不同系统中缺乏统一的键,我需要从现有数据中使用代理键(SK)查找根据。SK 数据集非常大(超过 5000 万键)。是否可以/建议在没有数据库查找的情况下缓存这样的数据集以进行流内转换(映射)?如果是,什么是缓存限制?如果没有,Flink 有哪些替代方案?
1 回答
有几个选项
当地地图
如果代理键永远不会改变,您可以将其加载RichMapFunction#open
并执行查找。这当然意味着您必须调整内存设置,以使 Flink 不会尝试为自己的操作占用所有内存。
一些快速的数学运算:假设两个键都是长度为 10 的字符串。它们每个都需要 40 个字节的字符在内存中。通过一些对象开销,我们将达到每个条目约 50 个字节。对于 50M 条目,我们需要 2.5 GB RAM 来存储它。因为哈希映射会有一些开销,所以我计划使用 3 GB RAM。
所以如果你的任务管理器有 8GB,我会设置taskmanager.memory.size
为 4GB。
Ofc,你需要确保同一个任务管理器的不同任务不会两次加载同一张地图。此外,我会选择一种适合尽快加载数据的格式(例如,Avro),因为慢速解析会大大减少启动和恢复时间。
基于状态的
如果内存存在问题或数据正在更改,您还可以将查找数据建模为映射状态。我会为该查找数据添加第二个输入并使用KeyedCoProcessFunction
. 馈送来自地图状态的第二个输入的任何内容。该状态应使用 Rocks-db 后端,以便数据有效地驻留在磁盘上。
加入数据
查找也可以建模为连接。如果您已经在使用 Table API,请查看Join with Temporal Table。这将在内部使用基于状态的方法,但更加简洁。您还可以将 DataStream 与 Tables 混合使用。