如何解决Flink keyBy与RichParallelSourceFunction
我正在学习flink,并试图理解一些概念。这里有几个问题:
- 在流上进行
keyBy
操作和从RichParallelSourceFunction
子对象(例如FlinkKinesisConsumer
)获取源有什么区别?这两个操作都会分割流。 - 还尝试实现一个非常简单的keyBy运算符来理解它,如下所示:
DataStream input = env.fromElements("1","2","3","4","5","6") .keyBy((KeySelector<String,Integer>) value -> Integer.parseInt(value) % 2); DataStream parsed = input.map(new MyMapper()); DataStream parsedStr = input.map(new MyStrMapper()); parsed.print(); parsedStr.print(); env.execute("myParser");
但是我得到的输出令人困惑:
3> 1
3> 2
3> 3
3> 4
3> 5
3> 6
3> I am 1
3> I am 2
3> I am 3
3> I am 4
3> I am 5
3> I am 6
这意味着在子任务3上执行的所有操作。有人可以帮助解释原因吗?
解决方法
(1)使用keyBy
与使用RichParallelSourceFunction
之间的区别?
每次使用keyBy
时,流记录必须经过序列化/反序列化,并且可能会通过网络发送。另一方面,可以将源实例链接到后续操作,这意味着流记录只是作为对象传递到java堆上。
当您具有Kafka或Kinesis之类的多个源实例时,它们不会划分流。每个实例都独立地连接到相关的代理/服务器,以处理已分配给它们处理的分区/碎片的记录。因此,使用RichParallelSourceFunction
,您可以实现性能更高的管道,而序列化/反序列化和联网所需的开销更少。
(2)为什么所有内容都将进入子任务3?
将KeySelector
函数的结果进行哈希处理,并将这些哈希值取为mod 128(假设您尚未重新配置密钥组的数量),以将每个密钥映射到密钥组。然后Flink确定哪个子任务负责这些关键组。
鉴于您的键函数只能返回两个不同的值(0和1),因此您只会看到一个或两个不同的子任务正在使用。显然0和1都哈希到已分配给子任务3的键组。
只要有可能,最好有一个比集群的并行性大得多的密钥空间。
参考
有关更多信息,请参阅我对以下问题的回答:
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。