Flink物理分区的几种方式

随机分区(shuffle)

最简单的重分区方式就是shuffle,通过调用DataStream的.shuffle()方法,将上游数据随机分配到下游的并行任务中
在这里插入图片描述

轮询分区(Round-Robin)

轮询也是常见的重分区方式,通过调用DataStream的.rebalance()方法,将上游的数据平均分配到下游所有的并行任务中
在这里插入图片描述

重缩放分区(rescale)

重缩放分区和轮询分区非常类型,当调用resacle()方法时,底层调用的其实就是Round-Robin算法进行轮询。
不同的是,rescale重缩放分区会将上游不同的数据来源分为不同的“团体”,在下游的同一团体内,对所有slot进行轮询分发。
从底层实现上看,rebalance 和 rescale 的根本区别在于任务之间的连接机制不同。rebalance 将会针对所有上游任务(发送数据方)和所有下游任务(接收数据方)之间建立通信通道,这是一个笛卡尔积的关系;而 rescale 仅仅针对每一个任务和下游对应的部分任务之间建立通信通道,节省了很多资源。

在这里插入图片描述

广播(broadcast)

严格意义上来说,广播并不能算作重分区的一种方式,它会将数据在所有分区都保留一份。通过调用.broadCast()方法,将上游输入数据发送到下游所有的并行任务中

全局分区(global)

全局分区也是一种特殊的分区方式,通过调用.global()方法,会将所有的输入流数据都发送到下游算子的第一个并行子任务中去。这就相当于强行让下游任务并行度变成了 1,所以使用这个操作需要非常谨慎,可能对程序造成很大的压力。

自定义分区

当 Flink 提供的所有分区策略都不能满足用户的需求时, 我们可以通过使用partitionCustom()方法来自定义分区策略。

public class _14CustomPartitionTest {
    public static void main(String[] args) throws Exception {
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        // 按照奇偶数进行分区
        DataStreamSource<Integer> streamSource = env.fromElements(1, 2, 3, 4, 5, 6, 7, 8);

        // 参数1:自定义的Partitioner分区器
        streamSource.partitionCustom(new Partitioner<Integer>() {
            @Override
            public int partition(Integer key, int numPartitions) {
                return key % 2;
            }
        }, new KeySelector<Integer, Integer>() { // 参数2:应用分区器的字段,或者直接像keyBy一样直接指定字段或者索引
            @Override
            public Integer getKey(Integer value) throws Exception {
                return value;
            }
        })
                .print();

        env.execute();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值