Flink keyBy 与 RichParallelSourceFunction
Flink keyBy vs 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
时,流记录都必须经过 serialization/deserialization,并且很可能会通过网络发送。另一方面,源实例可以 链接 到后续操作,这意味着流记录只是作为 java 堆上的对象传递。
当您有 Kafka 或 Kinesis 之类的多个源实例时,它们不会划分流。每个实例独立地连接到相关的 brokers/servers 来处理它们被分配处理的 partitions/shards 的记录。因此,使用 RichParallelSourceFunction
,您有可能以更少的 serialization/deserialization 和网络开销实现性能更高的管道。
(2) 为什么所有内容都转到子任务 3?
你的 KeySelector
函数的结果被散列,这些散列值被取 mod 128(假设你没有重新配置密钥组的数量)将每个密钥映射到 关键组。然后 Flink 确定哪个子任务负责这些关键组。
鉴于您的关键函数只能 return 两个不同的值(0 和 1),您只会看到一个或两个不同的子任务在使用中。显然 0 和 1 都散列到已分配给子任务 3 的密钥组。
只要有可能,最好有一个键 space 明显大于集群的并行度。
参考资料
要了解更多信息,请参阅我对这些问题的回答:
我正在学习 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
时,流记录都必须经过 serialization/deserialization,并且很可能会通过网络发送。另一方面,源实例可以 链接 到后续操作,这意味着流记录只是作为 java 堆上的对象传递。
当您有 Kafka 或 Kinesis 之类的多个源实例时,它们不会划分流。每个实例独立地连接到相关的 brokers/servers 来处理它们被分配处理的 partitions/shards 的记录。因此,使用 RichParallelSourceFunction
,您有可能以更少的 serialization/deserialization 和网络开销实现性能更高的管道。
(2) 为什么所有内容都转到子任务 3?
你的 KeySelector
函数的结果被散列,这些散列值被取 mod 128(假设你没有重新配置密钥组的数量)将每个密钥映射到 关键组。然后 Flink 确定哪个子任务负责这些关键组。
鉴于您的关键函数只能 return 两个不同的值(0 和 1),您只会看到一个或两个不同的子任务在使用中。显然 0 和 1 都散列到已分配给子任务 3 的密钥组。
只要有可能,最好有一个键 space 明显大于集群的并行度。
参考资料
要了解更多信息,请参阅我对这些问题的回答: