我正在为某些实时数据计算实现Flink数据流。这样我就可以从两种类型的源中获取数据流的价值。而且我需要根据某些键进行一些转换。当我使用RichCoMapFunction时,Mapstate对全局不可见。我的程序如下
class Transformer extends RichCoMapFunction[(String, Map[String, String]), (String, Map[String, String]), Map[String, String]] {
private var sourceMap1: MapState[String, Map[String, String]] = _
private var sourceMap2: MapState[String, Map[String, String]] = _
override def map1(in1: (String, Map[String, String])): Map[String, String] = {
sourceMap1.put(in1._2("key"), in1._2)
println(sourceMap1.keys()) // Working with updated values
println(sourceMap2.keys()) // Return empty value always
return in1._2
}
override def map2(in2: (String, Map[String, String])): Map[String, String] = {
sourceMap2.put(in2._2("key"), in2._2)
println(sourceMap1.keys()) // Return empty value always
println(sourceMap2.keys()) // Working with updated values
return in2._2
}
override def open(parameters: Configuration): Unit = {
val desc1: MapStateDescriptor[String, Map[String, String]] = new MapStateDescriptor[String, Map[String, String]]("sourceMap1", classOf[String], classOf[Map[String, String]])
sourceMap1 = getRuntimeContext.getMapState(desc1)
val desc2: MapStateDescriptor[String, Map[String, String]] = new MapStateDescriptor[String, Map[String, String]]("sourceMap2", classOf[String], classOf[Map[String, String]])
sourceMap2 = getRuntimeContext.getMapState(desc2)
}
}
由于其声明为全局,因此我需要在map1函数中访问sourceMap2。但是,当我尝试在map1函数中打印sourceMap2的键时,它总是返回为空值。但是,如果我要在map1函数中打印sourceMap1,则意味着它将打印所有添加的键。
答案 0 :(得分:0)
使用键控状态时,Flink将为每个键值存储一个单独的状态值。这意味着,如果您有一个状态为m
的有状态映射器s
,并且处理了(x1, y1)
为键的记录(x2, y2)
和x
,则Flink将存储{ {1}}和s(x1) = (x1, v1)
处于其状态后端。
在处理s(x2) = (x2, v2)
时,您只能访问(x2, y2)
,而不能访问s(x2)
。
我认为这就是为什么您看到空s(x1)
的原因。 MapState
和map1
的传入记录将具有不同的map2
,因此,您需要在keys
中访问sourceMap2
作为密钥(不是映射密钥,而是map1
键),尚未为其存储键值对。这同样适用于keyBy
,在您尚未存储任何键值对的键下访问map2
。
答案 1 :(得分:0)
您的Transformer类将应用于两个连接的键控流。 sourceMap1和sourceMap2是 keyed状态,这意味着您为两个连接的流中的每个键都有一个单独的嵌套哈希图。每次调用map1或map2时,一对映射就在范围之内,即与要映射的项的键相对应的一对。
如果您想让全局状态在所有键之间共享,请查看broadcast state pattern。