【问题标题】:Flink keyBy vs RichParallelSourceFunctionFlink keyBy vs RichParallelSourceFunction
【发布时间】:2020-10-30 17:35:23
【问题描述】:

我正在学习 flink 并试图理解一些概念。这里有几个问题:

  1. keyBy 对流的操作和从RichParallelSourceFunctionFlinkKinesisConsumer 这样的子类获取源之间有什么区别?两种操作都会划分流。
  2. 还尝试实现一个非常简单的 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 上执行的所有操作。有人可以帮助解释原因吗?

【问题讨论】:

    标签: java apache-flink flink-streaming


    【解决方案1】:

    (1) 使用keyBy 和使用RichParallelSourceFunction 的区别?

    每次使用keyBy时,流记录都必须经过序列化/反序列化,并且很可能会通过网络发送。另一方面,源实例可以链接到后续操作,这意味着流记录只是作为 Java 堆上的对象传递。

    当您有多个源实例(例如 Kafka 或 Kinesis)时,它们不会划分流。每个实例独立地连接到相关的代理/服务器,以处理分配给它们处理的分区/分片的记录。因此,使用RichParallelSourceFunction,您可以实现性能更高的管道,同时减少序列化/反序列化和网络的开销。

    (2) 为什么一切都转到子任务 3?

    您的KeySelector 函数的结果被散列,这些散列值取 mod 128(假设您没有重新配置键组的数量)以将每个键映射到一个 键组 . Flink 然后确定哪个子任务负责这些关键组。

    鉴于您的键函数只能返回两个不同的值(0 和 1),您只会看到一个或两个不同的子任务在使用中。显然 0 和 1 都散列到已分配给子任务 3 的键组。

    只要有可能,最好有一个显着大于集群并行度的键空间。

    参考文献

    要了解更多信息,请参阅我对这些问题的回答:

    【讨论】:

      猜你喜欢
      • 2022-12-02
      • 1970-01-01
      • 1970-01-01
      • 2020-12-24
      • 1970-01-01
      • 2018-02-27
      • 1970-01-01
      • 2019-05-26
      • 1970-01-01
      相关资源
      最近更新 更多