Flink入门案例-WordCount

Flink入门案例-WordCount

新建一个maven工程,在开发之前,要模拟Flink的开发环境,搭建本地的Flink的开发环境,引入依赖

<dependencies> 
        <dependency> 
            <groupId>org.apache.flink</groupId> 
            <artifactId>flink-java</artifactId> 
            <version>1.10.1</version> 
        </dependency> 
        <dependency> 
            <groupId>org.apache.flink</groupId> 
            <artifactId>flink-streaming-java_2.12</artifactId> 
            <version>1.10.1</version> 
        </dependency> 
    </dependencies> 

Flink是基于数据流的处理方式,但是在处理数据的同时,也提供了批处理的处理方式,所以分别测试一下批处理和流处理的不同

一、批处理方式

1:创建执行环境

// 创建执行环境
ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

2:从文件中读取数据

// 从文件中读取数据
String inputPath = "resources/hello.txt";
DataSource<String> inputDataSet = env.readTextFile(inputPath);

3:对数据集进行处理,转换成(word,1)统计

// 对数据集进行处理,按照空格分词展开,转换成(word,1)这样的二元组进行统计
DataSet<Tuple2<String, Integer>> result = inputDataSet
    		   .flatMap(new MyFlatMapper())
                .groupBy(0)     // 按照第一个位置的word进行分组
                .sum(1);          // 将第二个位置上的数据求和

        result.print();

注意:这里需要在flatMap方法中传入一个自定义的类,用于数据的处理逻辑

4:自定义类,实现FlatMapFunction接口

// 自定义类,实现FlatMapFunction接口
// 定义泛型,FlatMapFunction<输入类型,输出类型>
public static class MyFlatMapper implements FlatMapFunction<String, Tuple2<String, Integer>> {

    @Override
    public void flatMap(String s, Collector<Tuple2<String, Integer>> collector) throws Exception {

        // 按照空格分词
        String[] words = s.split(" ");

        // 遍历words,包成二元组输出
        for (String word: words) {
            collector.collect(new Tuple2<>(word, 1));
        }
    }

以上这些方法就是批处理的大致流程,整体代码如下:

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

        // 创建执行环境
        ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

        // 从文件中读取数据
        String inputPath = "resources/hello.txt";

        DataSource<String> inputDataSet = env.readTextFile(inputPath);

        // 对数据集进行处理,按照空格分词展开,转换成(word,1)这样的二元组进行统计
        DataSet<Tuple2<String, Integer>> result = inputDataSet.flatMap(new MyFlatMapper())
                .groupBy(0)     // 按照第一个位置的word进行分组
                .sum(1);          // 将第二个位置上的数据求和

        result.print();
    }

    // 自定义类,实现FlatMapFunction接口
    public static class MyFlatMapper implements FlatMapFunction<String, Tuple2<String, Integer>> {

        @Override
        public void flatMap(String s, Collector<Tuple2<String, Integer>> collector) throws Exception {

            // 按照空格分词
            String[] words = s.split(" ");

            // 遍历words,包成二元组输出
            for (String word: words) {
                collector.collect(new Tuple2<>(word, 1));
            }
        }
    }
}

二、流处理

1:创建执行环境

// 创建执行环境(流处理的执行环境)
StreamExecutionEnvironment env = StreamExecutionEnvironment
    .getExecutionEnvironment();
// 可以设置线程数
env.setParallelism(8);

2:从文件读取数据的做法和批处理的一致,现在实现一下监听端口处理数据

在实际的开发环境中,监听的主机名和端口号都是动态获取的,并不是固定的一个写在代码里

①用parameter tool工具从程序启动参数中配置

// 用parameter tool 工具从程序启动参数中提取配置项
ParameterTool parameterTool = ParameterTool.fromArgs(args);
// host 和 port 是在数据配置项中配置的,可以更改名字
String host = parameterTool.get("host");
int port = parameterTool.getInt("port");

②从socket文本读取数据

// 从socket文本流读取数据
DataStreamSource<String> inputDataStream = env.socketTextStream(host, port);

3:基于数据流进行转换操作

// 基于数据流进行转换计算
SingleOutputStreamOperator<Tuple2<String, Integer>> result =  
    inputDataStream.flatMap(new WordCount.MyFlatMapper())
    .keyBy(0)
    .sum(1);

4:指定任务

// 指定任务
env.execute();

5:自定义类,实现FlatMapFunction接口

 // 自定义类,实现FlatMapFunction接口
    public static class MyFlatMapper implements FlatMapFunction<String, Tuple2<String, Integer>> {

        @Override
        public void flatMap(String s, Collector<Tuple2<String, Integer>> collector) throws Exception {

            // 按照空格分词
            String[] words = s.split(" ");

            // 遍历words,包成二元组输出
            for (String word: words) {
                collector.collect(new Tuple2<>(word, 1));
            }
        }

以上这些方法就是流处理的大致流程,整体代码如下:

public class StreamWordCount {

    // 流式处理
    public static void main(String[] args) throws Exception {

        // 创建执行环境(流处理的执行环境)
        StreamExecutionEnvironment env = StreamExecutionEnvironment
            .getExecutionEnvironment();
        // 可以设置线程数
        env.setParallelism(8);

        // 用parameter tool 工具从程序启动参数中提取配置项
        ParameterTool parameterTool = ParameterTool.fromArgs(args);
        String host = parameterTool.get("host");
        int port = parameterTool.getInt("port");

        // 从socket文本流读取数据
        DataStreamSource<String> inputDataStream = env.socketTextStream(host, port);

        // 基于数据流进行转换计算
        SingleOutputStreamOperator<Tuple2<String, Integer>> result = inputDataStream.flatMap(new WordCount.MyFlatMapper())
                .keyBy(0)
                .sum(1);

        result.print();

        // 指定任务
        env.execute();
    }
// 自定义类,实现FlatMapFunction接口
    public static class MyFlatMapper implements FlatMapFunction<String, Tuple2<String, Integer>> {

        @Override
        public void flatMap(String s, Collector<Tuple2<String, Integer>> collector) throws Exception {

            // 按照空格分词
            String[] words = s.split(" ");

            // 遍历words,包成二元组输出
            for (String word: words) {
                collector.collect(new Tuple2<>(word, 1));
            }
        }
    }
}

三、批处理和流处理的区别

1:批处理就是在处理的时候根据批为单位进行处理,等到数据达到一批的数量之后,一批一批的处理,这时候数据处理就不能做到实时性。流处理就是将数据以流的形式进行传输处理,当数据流过来的时候就开始处理,具有很好的实时性

2:在代码实现上,创建执行环境时候的所调用的类也是不同的

批处理调用的类是ExecutionEnvironment类,而流处理调用的类是StreamExecutionEnvironment类,但是两者调用的方法都是getExecutionEnvironment方法获得执行环境

3:流处理的时候需要指定任务才可以启动程序执行,否则不会输出结果

4:在转换操作的时候也是一样,批处理返回的对象是DataSet类型,而流处理返回的对象是SingleOutputStreamOperator类型

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

牧码文

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

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

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

打赏作者

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

抵扣说明:

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

余额充值