Join 我可以使用Flink state执行连接吗?

Join 我可以使用Flink state执行连接吗?,join,apache-flink,Join,Apache Flink,我正在评估ApacheFlink的流处理,作为ApacheSpark的替代/补充。我们通常使用Spark解决的任务之一是数据充实 也就是说,我有来自IoT传感器的传感器ID数据流,我有一组传感器元数据。我想将输入流转换为传感器测量+传感器元数据流 在Spark中,我可以加入DStream和RDD case calss SensorValue(sensorId:Long,…) 案例类SensorMetadata(sensorId:Long,…) val sensorInput:DStream[Se

我正在评估ApacheFlink的流处理,作为ApacheSpark的替代/补充。我们通常使用Spark解决的任务之一是数据充实

也就是说,我有来自IoT传感器的传感器ID数据流,我有一组传感器元数据。我想将输入流转换为传感器测量+传感器元数据流

在Spark中,我可以加入DStream和RDD

case calss SensorValue(sensorId:Long,…)
案例类SensorMetadata(sensorId:Long,…)
val sensorInput:DStream[SensorValue]=readEventsFromKafka()
val staticMetadata:RDD[(长,传感器元数据)]=
spark.read.json(…).as[SensorMetadata]
.map{s=>(s.sensorId,s)}.rdd
val已加入:数据流[(SensorValue,SensorMetadata)]=
sensorInput.map{s=>(s.sensorId,s)}.transform{rdd:rdd[SensorValue]=>
join(静态元数据)
.map{case(,(s,m))=>(s,m)}//摆脱嵌套元组
}
我能用ApacheFlink玩同样的把戏吗?我看不到这方面的直接API。我唯一的想法是使用有状态转换——我可以在单个流中合并元数据和传感器事件,并使用Flink状态存储来存储元数据(伪代码):

val sensorInput:DataStream[SensorValue]=readEventsFromKafka()
val statistematadata:DataStream[SensorMetadata]=readMetadataFromJson()
val结果:数据流[(SensorValue,SensorMetadata)]=
sensorInput.keyBy(“传感器ID”)
.connect(staticMetadata.keyBy(“传感器ID”))
.flatMap{new RichCoFlatMapFunction(){
private val ValueState md=u2;;
覆盖def open=???//初始化值状态
def flatMap1(s:SensorEvent,s:Collector(SensorEvent,SensorMetadata))=
collector.collect(s,md.value)
def flatMap2(s:SensorMetadata,s:Collector[(SensorEvent,SensorMetadata)])=
md.update(s)
}}
这是正确的方法吗?当元数据不适合一台机器时,我可以在更大的范围内使用吗


谢谢

使用
CoFlatMapFunction
加入是一种常见的方法。然而,它有一个显著的缺点。当任一输入的元组到达并且您无法控制首先使用哪个输入时,就会调用该函数。因此,在开始时,您必须在元数据尚未完全读取时处理传感器事件。一种方法是缓冲一个输入的所有事件,直到另一个输入被消耗。另一方面,
CoFlatMapFunction
方法的好处是可以动态更新元数据。在您的代码示例中,两个输入都在join键上设置了键。这意味着输入是分区的,每个taskslot正在处理不同的密钥集。因此,您的元数据可能比计算机能够处理的要大(如果您配置RocksDB状态后端,则状态可以持久化到磁盘,因此您甚至不受内存大小的限制)


如果您要求在作业开始时必须显示所有元数据,并且元数据是静态的(不会更改),并且足够小,可以装入一台计算机,则还可以使用常规的
flatmap函数
,并从文件中加载
open()
方法中的元数据。与您的方法不同,这将是一个广播连接,其中每个taskslot在内存中都有完整的元数据。除了在使用事件数据时提供所有元数据外,这种方法的好处是您不需要对事件数据进行无序处理,因为它可以在任何机器上加入。

谢谢您的回答。唯一让我不清楚的是——我如何“缓冲”输入?您可以给我一些关键字来搜索吗?您可以创建第二个键控状态对象,将事件记录附加到其中,直到相应的元数据事件到达。发生这种情况时,加入并发出所有事件,清除事件状态并将元数据事件插入元数据状态。