Caching Apache Flink中大型(5000万)密钥集的代理密钥映射

Caching Apache Flink中大型(5000万)密钥集的代理密钥映射,caching,apache-flink,surrogate-key,Caching,Apache Flink,Surrogate Key,我有一个用例,apache flink进程必须集成来自多个源的近实时数据流(事件),但由于不同系统中缺少统一的密钥,我需要使用现有数据库中的代理密钥(SK)查找。SK数据集非常大(5000多万个密钥)。是否可以/建议在不使用DB查找的情况下为流内转换(映射)缓存此类数据集?如果是,缓存限制是什么?如果没有,Flink有哪些替代方案?有几种选择 本地地图 如果代理键从未更改,您可以将其加载到RichMapFunction#open中并执行查找。当然,这意味着您必须调整内存设置,以便Flink不会尝

我有一个用例,apache flink进程必须集成来自多个源的近实时数据流(事件),但由于不同系统中缺少统一的密钥,我需要使用现有数据库中的代理密钥(SK)查找。SK数据集非常大(5000多万个密钥)。是否可以/建议在不使用DB查找的情况下为流内转换(映射)缓存此类数据集?如果是,缓存限制是什么?如果没有,Flink有哪些替代方案?

有几种选择

本地地图 如果代理键从未更改,您可以将其加载到
RichMapFunction#open
中并执行查找。当然,这意味着您必须调整内存设置,以便Flink不会尝试为自己的操作占用所有内存

快速计算:假设两个键都是长度为10的字符串。它们在内存中都需要40字节的字符。在一些对象开销的情况下,每个条目大约有50个字节。对于5000万个条目,我们需要2.5 GB的RAM来存储它们。因为哈希映射会有一些开销,所以我计划使用3 GB RAM

因此,如果任务管理器有8GB,我会将其设置为4GB


Ofc,您需要确保同一任务管理器的不同任务不会两次加载同一映射。另外,我会选择一种适合尽快加载数据的格式(例如Avro),因为缓慢的解析将大大减少启动和恢复时间

基于国家的 如果内存问题或数据正在更改,也可以将查找数据建模为映射状态。我将为该查找数据添加第二个输入,并使用
keyedcomprocessfunction
。将来自第二个输入的任何内容馈送到映射状态。该州应使用rocks db后端,以便数据有效地驻留在磁盘上

连接数据
查找也可以建模为联接。如果您已经在使用表API,请查看。这将在内部使用基于状态的方法,但更加简洁。您也可以。

有几个选项

本地地图 如果代理键从未更改,您可以将其加载到
RichMapFunction#open
中并执行查找。当然,这意味着您必须调整内存设置,以便Flink不会尝试为自己的操作占用所有内存

快速计算:假设两个键都是长度为10的字符串。它们在内存中都需要40字节的字符。在一些对象开销的情况下,每个条目大约有50个字节。对于5000万个条目,我们需要2.5 GB的RAM来存储它们。因为哈希映射会有一些开销,所以我计划使用3 GB RAM

因此,如果任务管理器有8GB,我会将其设置为4GB


Ofc,您需要确保同一任务管理器的不同任务不会两次加载同一映射。另外,我会选择一种适合尽快加载数据的格式(例如Avro),因为缓慢的解析将大大减少启动和恢复时间

基于国家的 如果内存问题或数据正在更改,也可以将查找数据建模为映射状态。我将为该查找数据添加第二个输入,并使用
keyedcomprocessfunction
。将来自第二个输入的任何内容馈送到映射状态。该州应使用rocks db后端,以便数据有效地驻留在磁盘上

连接数据
查找也可以建模为联接。如果您已经在使用表API,请查看。这将在内部使用基于状态的方法,但更加简洁。您也可以。

“Ofc,您需要确保同一任务管理器的不同任务不会两次加载同一映射”您如何确保?您通常会使用在
open()
中初始化的静态变量,并在其周围进行一些同步
synchronized(staticMap){if(staticMap==null){staticMap=initializeMap();}}}
“Ofc,您需要确保同一任务管理器的不同任务不会两次加载同一个映射”如何确保?您通常会使用在
open()
中初始化的静态变量,并在其周围进行一些同步
synchronized(staticMap){if(staticMap==null){staticMap=initializeMap();}}}