我可以对group by使用自定义分区程序吗?

时间:2018-10-12 08:04:55

标签: apache-flink flink-streaming

比方说,我知道我的数据集是不平衡的,而且我知道密钥的分布。我想利用它编写一个自定义分区程序,以充分利用运算符实例。

我了解DataStream#partitionCustom。但是,如果我的流被加密,它是否仍可以正常工作?我的工作看起来像这样:

KeyedDataStream afterCustomPartition = keyedStream.partitionCustom(new MyPartitioner(), MyPartitionKeySelector())

DataStreamUtils.reinterpretAsKeyedStream(afterCustomPartition, new MyGroupByKeySelector<>()).sum()

我想要实现的是:

  • 具有流键通过按某个键,可以只用该键中的元素调用reduce函数。
  • 该小组根据一些自定义分区将工作划分为多个节点。
  • 自定义分区会根据并行运算符实例的数量返回一个数字(该数字将是固定的,并且不会进行重新缩放)。
  • 自定义分区从keyBy返回不同的值。但是,keyBy(x) = keyBy(y) => partition(x) = partition(y)
  • 具有pre-aggregation可以在分区之前最大程度地减少网络流量。

用例示例:

  • 数据集:[(0,A),(0,B),(0,C),(1,D),(2,E)]
  • 并行运算符实例数:2
  • 按功能分组:返回该对中的第一个元素
  • 分区功能:为键0返回0,为键1和2返回1。优点:处理可能将键0和1发送到同一操作员实例的数据偏移,这意味着一个操作员实例将收到80%数据集。

1 个答案:

答案 0 :(得分:2)

很遗憾,这是不可能的。 DataStreamUtils.reinterpretAsKeyedStream()要求对数据进行相同的分区,就像调用keyBy()一样。

此限制的原因是密钥组以及密钥如何映射到密钥组。密钥组是Flink分配密钥状态的单位。密钥组的数量决定了运算符的最大并行度,并使用setMaxParallelism()进行配置。使用内部哈希函数将密钥分配给密钥组。通过更改密钥的分区,同一密钥组的密钥将分布在无法使用的多台计算机上。

为了调整对计算机的密钥分配,您需要更改对密钥组的密钥分配。但是,没有公共或可访问的接口可以执行此操作。因此,Flink 1.6不支持自定义密钥分发。