橘子学Flink04之批处理&&流处理案例

本文详细介绍了使用Apache Flink进行批处理和流处理的实践,通过Java代码展示了如何统计文本文件中单词出现次数的批处理过程,以及如何模拟实时数据流并进行窗口聚合统计。批处理部分通过Flink读取文件,分组聚合实现单词计数;流处理部分则通过socket模拟数据源,设置时间窗口进行实时单词统计。
摘要由CSDN通过智能技术生成

我们设计一个需求就是统计一个文件里面各个单词出现的次数。

一、批处理

1、maven项目搭建

<dependency>
    <groupId>org.apache.flink</groupId>
     <artifactId>flink-clients_2.10</artifactId>
     <version>1.3.2</version>
 </dependency>
 <!--flink核心包-->
 <dependency>
     <groupId>org.apache.flink</groupId>
     <artifactId>flink-java</artifactId>
     <version>1.7.2</version>
 </dependency>
 <!--flink流处理包-->
 <dependency>
     <groupId>org.apache.flink</groupId>
     <artifactId>flink-streaming-java_2.12</artifactId>
     <version>1.7.2</version>
     <scope>provided</scope>
 </dependency>

2、Java代码编写

/**
 * @description: 单词统计(批数据处理)
 * @date: 2022-3-21 22:17
 * @version: 1.0
 */
import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.DataSet;
import org.apache.flink.api.java.ExecutionEnvironment;
import org.apache.flink.api.java.operators.DataSource;
import org.apache.flink.api.java.operators.FlatMapOperator;
import org.apache.flink.api.java.operators.UnsortedGrouping;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.util.Collector;
// 这里都是flink的包,注意了
/**
 * 单词统计(批数据处理)
 */
public class WordCount {
    public static void main(String[] args){
        // 1、获取flink的运行环境
        ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();
        // 2、用flink的运行环境,去获取待分析的数据
        String input = "E:\\file\\input\\sourceFile.txt";
        String output = "E:\\file\\output";
        // 3、处理数据
        // 3.1、将文本内容打散成一个个单词,存在DataSource中,其实就是个集合,这里是存的每一行数据,还没打散呢
        DataSource<String> lines = env.readTextFile(input);
        // 把每一行元素做一个施加作用,得到最后的一个结果,这里就是对上文的每一行都做一个拆分,打散为单词,SplitFun就是个实现类,下面我们实现了
        FlatMapOperator<String, Tuple2<String, Integer>> wordAndOne = lines.flatMap(new SplitFun());
        /**
         * 3.2、把相同的单词聚合到一起,根据单词内容进行聚合,意思就是把相同单词做一个聚合
         * 这里说明一下,在上一步,我们拆分了每一行的字符串,成为一个单词和计数1组成的二元组<hello,1>这样的,这一步我们将进行分组统计,言下之意
         * 就是我们统计一下hello有几个,直接用groupBy做分组,传参是0,意思就是我们以这个二元组的下标为0的元素做分组,也就是前面的单词,不按计数分组
         * 这个很好理解,因为你就是统计的单词的个数,自然就以单词分组。UnsortedGrouping就是没排序的分组集合。
         **/
        UnsortedGrouping<Tuple2<String, Integer>> grouped = wordAndOne.groupBy(0);
        /**
         * 3.3、把聚合到一起的数据进行累加处理,DataSet是批处理最主要的结构,这里累加的就是后面那个1了,所以下标传1,这里还是处理的上面那个二元组
         * 虽然他分组了,但是还是一个个的二元组。这里用DataSet这个父类接收,他有批处理的功能,我们就用这个。他是个多态的设计。
         **/
        DataSet<Tuple2<String, Integer>> result = grouped.sum(1);
        // 4、保存处理结果
        result.writeAsText(output);
        // 5、触发程序执行,随便传个执行语句,不传也行,不传就是走他的默认值
        try {
            env.execute("wordCount batch process");
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }

    /**
     * @Description //把输入进来的每一行元素根据空格切分,切分成一个一个的单词再把切分好的单词变成(单词,1)的组合
     * @Date 23:27 2022-3-21
     * @Param  * @param null
     * @return
     **/
    static class SplitFun implements FlatMapFunction<String,Tuple2<String,Integer>>{
        // value参数就是每一行字符串,out最后你处理完的输出到这里
        @Override
        public void flatMap(String value, Collector<Tuple2<String, Integer>> out) throws Exception {
            // 将文本内容打散成一个个单词,返回为一个字符串数组
            String[] words = value.split(" ");// hello you按照空格拆分转化为(hello,1)(you,1)后面聚合的时候直接把各个1相加就行了,就能直接计算总数了
            for (String word : words) {
                // 这里就是把单词放到Tuple2这个结构,比如hello,放进去成为hello,1这个元祖,每个单词都计数一次1,最后聚合的时候把各自的1相加,就知道有几个了
                Tuple2<String, Integer> wordAndOne = new Tuple2<>(word, 1);
                out.collect(wordAndOne);
            }
        }
    }
}

3、数据准备,运行程序,查看结果

数据准备一个文件读取:
在这里插入图片描述
执行程序,查看输出路径,看一下输出文件我们看到you出现了三次统计完成。
在这里插入图片描述

4、总结

总结我们看一个流程图:
在这里插入图片描述

二、流处理

批处理和流处理不同,批处理我们是准备了一个文件让他去读取,而流处理是不断的数据过来,让他处理。这里我们模拟一个socket程序,不断的发数据过来,然后flink程序这里做处理。
Socket模拟实时发送单词,使用Flink实时接收数据,对指定时间窗口内(如5s)的数据进行聚合统计,每隔1s汇总计算一次,并且把时间窗口内计算结果打印出来。

1、 代码实现



/**
 * @description: Socket模拟实时发送单词,使用Flink实时接收数据,对指定时间窗口内(如5s)的数据进行聚合统计,
 * 每隔1s汇总计算一次,并且把时间窗口内计算结果打印出来。
 *  teacher2 ip : 113.31.105.128
 * @date: 2022-3-21 23:33
 * @version: 1.0
 */

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;

/**
 * 	Socket模拟实时发送单词,使用Flink实时接收数据,对指定时间窗口内(如5s)的数据进行聚合统计,每隔1s汇总计算一次,并且把时间窗口内计算结果打印出来。
 teacher2 ip : 113.31.105.128
 */
public class WordCount {

    public static void main(String[] args) throws Exception {
        // 监听的ip和端口号,以main参数形式传入,约定第一个参数为ip,第二个参数为端口
        String ip = "127.0.0.1";
        int port = 8888;
        // 获取Flink流执行环境
        StreamExecutionEnvironment streamExecutionEnvironment = StreamExecutionEnvironment.getExecutionEnvironment();
        // 获取socket输入数据
        DataStreamSource<String> textStream = streamExecutionEnvironment.socketTextStream(ip, port);

        SingleOutputStreamOperator<Tuple2<String, Long>> tuple2SingleOutputStreamOperator = textStream.flatMap(new FlatMapFunction<String, Tuple2<String, Long>>() {
            @Override
            public void flatMap(String value, Collector<Tuple2<String, Long>> collector) throws Exception {
                String[] splits = value.split(" ");
                for (String word : splits) {
                    collector.collect(Tuple2.of(word, 1L));
                }
            }
        });

        // 根据key进行分组聚合,具体属性就是word
        SingleOutputStreamOperator<Tuple2<String, Long>> word = tuple2SingleOutputStreamOperator.keyBy(0)
                //.timeWindow(Time.seconds(2), Time.seconds(1))
                .sum(1);
        // 打印数据
        System.out.println("********************分割符**********************");
        word.print();
        // 触发任务执行
        streamExecutionEnvironment.execute("wordcount stream process");
    }
}

2、启动程序

直接run

3、在netcat上面执行发送字符串命令

至于如何安装netcat自己百度即可。https://blog.csdn.net/junR_980218/article/details/125374526

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值