flink数据流keyby api

fdbelqdn  于 2021-06-21  发布在  Flink
关注(0)|答案(1)|浏览(474)

我是flink的新手,以下是流媒体模式字数:

//x is the stream of (word, 1)
val x: DataStream[(String, Int)] = text
  .flatMap(_.toLowerCase.split("\\W+")) 
  .map((_, 1))

//keyBy on the word field, what does the Tuple here mean in y   
val y: KeyedStream[(String, Int), Tuple] = x.keyBy(0)  

val z: DataStream[(String, Int)] = y.sum(1)

z.print

假设 x 是一股 ("a", 1), ("b", 1), ("c",1),("a",1),("c",1),("c",1) 什么会 y 看起来像(我不明白) Tuple 这里的意思是),那是什么 z 看起来像?

j2cgzkjk

j2cgzkjk1#

当您指定keyby(0)时,您是通过流中元组的第一个元素对流进行键控,或者换句话说,您是通过单词字符串对流进行键控。但是,编译器无法确定键是字符串,因此此版本的keyby始终将键视为包含某个对象(即实际键)的元组。
如果你把keyby改写成 keyBy(_._1) 然后编译器将能够推断出密钥类型,y将是一个 KeyedStream[(String, Int), String] ,感觉应该会好些。
对流进行键控所完成的是对流进行分区,类似于sql中groupby将表拆分为不相交、不重叠的组的方式。因此,在这种情况下,流(“a”,1)、(“b”,1)、(“c”,1)、(“a”,1)、(“c”,1)、(“c”,1)在逻辑上分为三组:

("a",1), ("a",1)
("b",1)
("c",1), ("c",1), ("c",1)

然后,对每个元组计算sum(1)的结果是(在map/reduce意义上)通过将每个元组中所有元组的第二个字段相加来减少每个元组。所以,(“a”,1),(“a”,1)变成(“a”,2),依此类推。
而不是使用 z=y.sum(1) ,则更容易理解

val z: DataStream[(String, Int)] = y.reduce(new ReduceFunction[(String, Int)] {
  override def reduce(t1: (String, Int), t2: (String, Int)): (String, Int) =
    (t1._1, t1._2 + t2._2)
})

如果运行代码,您可以精确地看到z的样子。如果您给它足够的资源,它可以在三个独立的线程中运行(因为有三个不同的键)。我刚刚得到这些结果:

3> (a,1)
2> (c,1)
1> (b,1)
2> (c,2)
2> (c,3)
3> (a,2)

其中1>、2>和3>表示哪个线程负责该行输出。

相关问题