首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >flink DataStream keyBy API

flink DataStream keyBy API
EN

Stack Overflow用户
提问于 2019-01-13 13:43:11
回答 1查看 1.1K关注 0票数 1

我是Flink的新手,以下是流式模式字数:

代码语言:javascript
复制
//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是什么样子呢?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-01-13 21:20:30

当您指定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)在逻辑上被分成三组:

代码语言:javascript
复制
("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)相比,可能更容易理解,更完整地写成

代码语言:javascript
复制
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是什么样子。如果你给它足够的资源,它可以在三个单独的线程中运行(因为有三个不同的键)。我刚刚得到了以下结果:

代码语言:javascript
复制
3> (a,1)
2> (c,1)
1> (b,1)
2> (c,2)
2> (c,3)
3> (a,2)

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

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/54166390

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档