Flink教程(2) DataStream聚合 keyBy sum min和minBy区别

1. keyBy

keyBy是把数据流按照某个字段分区,下面用wordCount举例说明其用法

1.1 keyBy(0)

下面是个典型的wordCount程序,从数据源读取数据后,我们转换为元组Tuple2<String, Integer>。
这个元组有2个值,第一个是单词,第二个是1。
要按照不同的单词分组,就是按照元组Tuple2中下标为0的值分组,所以调用了keyBy(0)。

package com.pigg.test01;

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.util.Collector;

public class StreamWordCount {

    public static void main(String[] args) throws Exception {

        //1. create environment
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        //2. create dataStream source
        DataStreamSource<String> dataStream = env.socketTextStream("com.pigg", 8888);

        //3. trans
        SingleOutputStreamOperator<Tuple2<String, Integer>> wordAndOne = dataStream.flatMap(new Splitter());

        SingleOutputStreamOperator<Tuple2<String, Integer>> sumResult = wordAndOne
                .keyBy(0)
                .timeWindow(Time.seconds(5))
                .sum(1);

        //4. sink
        sumResult.print();

        //5. execute
        env.execute("StreamWordCount");
    }

    public static class Splitter implements FlatMapFunction<String, Tuple2<String, Integer>> {

        @Override
        public void flatMap(String line, Collector<Tuple2<String, Integer>> collector) throws Exception {
            for (String word : line.split(" ")){
                collector.collect(new Tuple2<String, Integer>(word, 1));
            }
        }
    }
}

1.2 keyBy(“someKey”)

先定义POJO,注意一定要有无参构造方法,重写toString()是为了输出好看。

package com.pigg.test01;

public class WordCount {

    private String word;

    private Long count;

    public WordCount() {
    }

    public WordCount(String word, Long count) {
        this.word = word;
        this.count = count;
    }

    public String getWord() {
        return word;
    }

    public void setWord(String word) {
        this.word = word;
    }

    public Long getCount() {
        return count;
    }

    public void setCount(Long count) {
        this.count = count;
    }

    @Override
    public String toString() {
        return "WordCount{" +
                "word='" + word + '\'' +
                ", count=" + count +
                '}';
    }
}

下面是wordCount程序,keyBy(“word”)和sum(“count”)它们的参数"word","count"必须和POJO里字段一致。

package com.pigg.test01;

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.windowing.time.Time;
import org.apache.flink.util.Collector;

public class StreamWordCountBean {

    public static void main(String[] args) throws Exception {

        //1. create environment
        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        //2. create dataStream source
        DataStreamSource<String> dataStream = env.socketTextStream("com.pigg", 8888);

        //3. trans
        SingleOutputStreamOperator<WordCount> wordAndOne = dataStream.flatMap(new Splitter());

        SingleOutputStreamOperator<WordCount> sumResult = wordAndOne
                .keyBy("word")
                .timeWindow(Time.seconds(5))
                .sum("count");

        //4. sink
        sumResult.print();

        //5. execute
        env.execute("StreamWordCountBean");
    }

    public static class Splitter implements FlatMapFunction<String, WordCount> {

        @Override
        public void flatMap(String line, Collector<WordCount> collector) throws Exception {
            for (String word : line.split(" ")){
                collector.collect(new WordCount(word, 1L));
            }
        }
    }
}

2. min和minBy区别

Flink的dataStream聚合函数有如下:

keyedStream.sum(0);
keyedStream.sum("key");
keyedStream.min(0);
keyedStream.min("key");
keyedStream.max(0);
keyedStream.max("key");
keyedStream.minBy(0);
keyedStream.minBy("key");
keyedStream.maxBy(0);
keyedStream.maxBy("key");

2.1 min

package com.pigg.test01;

import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.api.java.tuple.Tuple3;
import org.apache.flink.streaming.api.datastream.DataStreamSource;
import org.apache.flink.streaming.api.datastream.SingleOutputStreamOperator;
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;

import java.util.ArrayList;
import java.util.List;

public class StreamMinTest {

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

        List data = new ArrayList<Tuple3<String, String, Integer>>();
        data.add(new Tuple3<>("男", "老王", 80));
        data.add(new Tuple3<>("男", "小王", 25));
        data.add(new Tuple3<>("男", "老李", 85));
        data.add(new Tuple3<>("男", "小李", 20));

        DataStreamSource peoples = env.fromCollection(data);
		
		//求年龄最小的人
        SingleOutputStreamOperator minResult = peoples.keyBy(0).min(2);
        minResult.print();

        env.execute("StreamMinTest");
    }
}

输出结果:

1> (,老王,80)
1> (,老王,25)
1> (,老王,25)#年龄算对了,但是别的字段还是第一个老王
1> (,老王,20)#年龄最小的居然还是第一个老王?

min根据指定的字段取最小,它只返回最小的那个字段,而不是整个数据元素,对于其他的字段取了第一次取的值,不能保证每个字段的数值正确。

2.2 minBy

把上面的程序中min换成minBy

SingleOutputStreamOperator minResult = peoples.keyBy(0).minBy(2);

输出结果:

1> (,老王,80)
1> (,小王,25)
1> (,小王,25)
1> (,小李,20)#年龄最小的人找到了,是20岁的小李

minBy根据指定字段取最小,返回的是整个元素。
上一篇Flink教程(一) Flink DataStream 创建数据源 转换算子
下一篇Flink教程(三) 大白话 时间 窗口 watermark
如果本文对您有帮助,就点个赞👍吧

  • 12
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Flink双流join datastream是指使用Flink流处理框架对两个数据流进行连接操作。在Flink中,双流join是一种常用的操作,它允许我们将两个不同的数据流合并在一起,并在两个流中相关的事件匹配时执行自定义的操作。 在Flink中,我们可以使用KeyedStream对数据流进行分区,然后使用join操作将两个KeyedStream连接在一起。Join操作可以根据时间窗口或关联键对事件进行匹配,并且可以配置不同的匹配策略。常见的匹配策略有inner join(内连接),outer join(外连接),left outer join(左外连接)和right outer join(右外连接)等。 在双流join的过程中,Flink会维护一个状态来存储窗口中的数据,并持续更新状态。当两个流中的事件匹配时,Flink将执行定义的操作,并将结果发送到输出流中。 双流join是一种灵活且强大的操作,可以应用于各种场景。例如,可以将点击流数据和用户行为数据进行join,以识别用户喜好;可以将订单数据和库存数据进行join,以实时监控库存状态;可以将实时交易数据和市场数据进行join,以发现交易机会等。 总而言之,Flink双流join datastream是一种在流处理中常用的操作,它可以将两个数据流合并在一起,并根据特定的条件进行匹配和操作。这种操作可以应用于各种场景,并且Flink提供了丰富的功能和配置选项来实现不同的join策略和需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

瑟 王

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值