假设我知道我的数据集不平衡并且我知道键的分布。我想利用它来编写一个自定义分区器,以充分利用运算符实例。
我知道关于数据流#partitionCustom https://ci.apache.org/projects/flink/flink-docs-master/api/java/org/apache/flink/streaming/api/datastream/DataStream.html#partitionCustom-org.apache.flink.api.common.functions.Partitioner-org.apache.flink.api.java.functions.KeySelector-。但是,如果我的流被锁定,它仍然可以正常工作吗?我的工作看起来像这样:
KeyedDataStream afterCustomPartition = keyedStream.partitionCustom(new MyPartitioner(), MyPartitionKeySelector())
DataStreamUtils.reinterpretAsKeyedStream(afterCustomPartition, new MyGroupByKeySelector<>()).sum()
我想要实现的是:
- 根据某个键拥有一个流 keyBy ,以便仅使用该键中的元素调用reduce函数。
- 该组根据一些自定义分区将工作拆分到节点之间。
- 自定义分区根据并行运算符实例的数量返回一个数字(该数字将被修复并且不会重新缩放)。
- 自定义分区从 keyBy 返回不同的值。然而,
keyBy(x) = keyBy(y) => partition(x) = partition(y)
.
- Having 预聚合 https://stackoverflow.com/questions/51634189/does-flink-support-map-side-aggregations-streaming在分区之前最大限度地减少网络流量。
用例示例:
- 数据集:[(0, A), (0, B), (0, C), (1, D), (2, E)]
- 并行算子实例数量:2
- 按函数分组:返回该对的第一个元素
- 分区函数:对于键 0 返回 0,对于键 1 和 2 返回 1。优点:处理可能将键 0 和 1 发送到同一运算符实例的数据倾斜,这意味着一个运算符实例将接收 80% 的数据集。
不幸的是这是不可能的。DataStreamUtils.reinterpretAsKeyedStream()
要求数据进行相同的分区,就像您调用keyBy()
.
造成此限制的原因是密钥组以及密钥如何映射到密钥组。密钥组是 Flink 分配密钥状态的单位。键组的数量决定了算子的最大并行度,配置为setMaxParallelism()
。密钥通过内部哈希函数分配给密钥组。通过更改密钥的分区,同一密钥组的密钥将分布在多台机器上,这是行不通的。
为了调整机器的密钥分配,您需要更改密钥组的密钥分配。但是,没有公共或可访问的接口来执行此操作。因此,Flink 1.6 中不支持自定义密钥分配。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)