flink之重分区算子

本文介绍了Flink数据流处理中的几种重分区算子,包括shuffle、rebalance、rescale、广播、全局分区等,详细解释了它们的工作原理和应用场景,并提供了一个代码示例来展示这些分区策略的使用。
摘要由CSDN通过智能技术生成

重分区算子(物理分区算子):(keyBy、随机分区(shuffle)、轮询分区Round-Robin(rebalance)、重缩放分区(rescale)、广播(broadcast)、全局分区(global)、forward、自定义分区(Custom))

keyBy和shuffle(经过随机分区之后,得到的依然是一个DataStream)不必多说。

轮询分区算子rebalance(通过DataStream来调用):

简单来说就是发牌。rebalance使用的是Round-Robin负载均衡算法,可以将输入流数据平均分配到下游的并行任务中去.

 重缩放分区(rescale)

重缩放分区和轮询分区非常相似。当调用rescale()方法时,其实底层也是使用Round-Robin算法进行轮询,但是只会将数据轮询发送到下游并行任务的一部分中。rescale的做法是分成小团体,发牌人只给自己团体内的所有人轮流发牌。假设上游2个分区,下游4个分区,rescale会先分组(不是keyBy,而是普通含义上的分组,比如上游1分区分配下游1、2号分区,2号分区分配下游3、4号分区,然后在组内轮询发送)

广播(broadcast):

这种方式其实不应该叫做“重分区”,因为经过广播之后,数据会在不同的分区都保留一份,可能进行重复处理。可以通过调用DataStream的broadcast()方法,将输入数据复制并发送到下游算子的所有并行任务中去。

 全局分区(global):

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

forward:一对一,要求上下游的并行度得相同 :

 

自定义分区(Custom):

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

代码测试:


import com.sandra.bean.WaterSensor;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.java.functions.KeySelector;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.KeyedStream;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

public class Flink10_Transform_Repartition {
    public static void main(String[] args) throws Exception {
        //todo 1.获取流的执行环境
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        env.setParallelism(4);

        //todo 2.从端口读取数据
        DataStreamSource<String> streamSource = env.socketTextStream("hadoop102", 9999);

        //todo 3.使用map将读取的数据转为WaterSensor
        SingleOutputStreamOperator<WaterSensor> result = streamSource.map(new MapFunction<String, WaterSensor>() {
            @Override
            public WaterSensor map(String line) throws Exception {
                String[] waterSensorWords = line.split(" ");


                return new WaterSensor(waterSensorWords[0], Long.parseLong(waterSensorWords[1]), Integer.parseInt(waterSensorWords[2]));
            }
        }).setParallelism(2);

        //将上游数据打印,看看数据去往上游数据的哪个分区(上游有2个分区)
        result.print("原始数据").setParallelism(2);//map和print的并行度都设置为2,目的是将它们串到一起

        //todo 4.使用keyby将相同的id的数据放到一块
        KeyedStream<WaterSensor, String> keyedStream = result.keyBy(new KeySelector<WaterSensor, String>() {
            @Override
            public String getKey(WaterSensor value) throws Exception {
                return value.getId();
            }
        });

        DataStream<WaterSensor> shuffle = result.shuffle();//并行度为4
        DataStream<WaterSensor> rebalance = result.rebalance();//并行度为4
        DataStream<WaterSensor> rescale = result.rescale();//并行度为4


//        KeyedStream<WaterSensor, Tuple> keyedStream1 = result.keyBy("id");

        //将下游的数据打印出来,看看上游两个分区的数据分别去往下游的哪个分区
        keyedStream.print("keyBy");//并行度为4
        shuffle.print("shuffle");//并行度为4
        rebalance.print("rebalance");//并行度为4
        rescale.print("rescale");//并行度为4



        env.execute();

    }
}

测试结果为:

Flink程序运用的算子有很多种,以下是几个常用的算子示例: 1. Map算子:对输入流中的每个元素应用一个函数,并返回一个新的元素。可以用来进行数据的转换和处理。 ```java DataStream<Integer> input = ...; DataStream<Integer> result = input.map(new MapFunction<Integer, Integer>() { @Override public Integer map(Integer value) throws Exception { return value * 2; } }); ``` 2. Filter算子:根据指定的条件过滤输入流中的元素,只保留满足条件的元素。 ```java DataStream<Integer> input = ...; DataStream<Integer> result = input.filter(new FilterFunction<Integer>() { @Override public boolean filter(Integer value) throws Exception { return value % 2 == 0; } }); ``` 3. KeyBy算子:根据指定的键对输入流进行分组,将具有相同键的元素分到同一个分区中。 ```java DataStream<Tuple2<String, Integer>> input = ...; KeyedStream<Tuple2<String, Integer>, String> keyedStream = input.keyBy(0); ``` 4. Reduce算子:对输入流中具有相同键的元素进行归约操作,返回一个新的元素。 ```java KeyedStream<Tuple2<String, Integer>, String> input = ...; DataStream<Tuple2<String, Integer>> result = input.reduce(new ReduceFunction<Tuple2<String, Integer>>() { @Override public Tuple2<String, Integer> reduce(Tuple2<String, Integer> value1, Tuple2<String, Integer> value2) throws Exception { return new Tuple2<>(value1.f0, value1.f1 + value2.f1); } }); ``` 5. Window算子:将输入流划分为不重叠的窗口,并对每个窗口中的元素进行计算。 ```java DataStream<Tuple2<String, Integer>> input = ...; DataStream<Tuple2<String, Integer>> result = input .keyBy(0) .window(TumblingProcessingTimeWindows.of(Time.seconds(5))) .sum(1); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值