Flink的分区算子和自定义分区器
一、分区算子
关键:上游的某个 SubTask 的数据该发送到下游的哪一个 SubTask 中。
1)ShufflePartitioner
随机选取下游的 SubTask。
*.shuffle();
2)BroadcastPartitioner
将数据分发到下游的每一个 SubTask 中。
*.broadcast();
3)GlobalPartitioner
将数据分发到下游的第一个 SubTask 中。
*.global();
4)RebalancePartitioner
将数据轮询发到下游的 SubTask 中,可能存在数据的网络传输,可以解决数据倾斜问题。
*.rebalance();
5)RescalePartitioner
不存在数据的网络传输,按组进行轮询发到下游的 SubTask 中,而不是按整体轮询。
如:上游 2 个分区【0,1】,下游 4 个分区【2,3,4,5】,0号分区会轮询发到2号和3号分区,1号分区会轮询发到4号和5号分区;
反之,上游 4 个分区【0,1,2,3】,下游 2 个分区【4,5】,0号,1号分区会发到4号分区,2号,3号分区会发到4号分区;
*.rescale();
6)ForwardPartitioner
只有在上游和下游的并行度相同且没有指定相关分区器的时候,才会使用ForwardPartitioner。
上下游SubTask一一对应进行下发。
二、自定义分区器代码示例
1)自定义分区器
public class MyPartitioner implements Partitioner<String> {
@Override
public int partition(String key, int numPartitions) {
return Integer.parseInt(key) % numPartitions;
}
}
2)应用自定义的分区器
public class PartitionCustomDemo {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
env.setParallelism(2);
DataStreamSource<String> socketDS = env.socketTextStream("localhost", 7777);
socketDS
.partitionCustom(new MyPartitioner(), r->r)
.print();
env.execute();
}
}