Flink 经典WordCount入门案例

  • 以批处理的方式从文本读取数据:
package com.hmi1024.flink.example;

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.java.ExecutionEnvironment;
import org.apache.flink.api.java.operators.*;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.util.Collector;

/**
 * 需求:使用批处理的方式进行单词的计算
 * 读取文件中的数据,对单词进行空格拆分,对每个单词进行计算,然后分组累加
 *
 * flink1.12版本之前才区分流和批,flink1.12版本后实现流批的统一
 * Flink批处理的数据抽象:DataSet
 * Flink流处理的数据抽象:DataStream
 */
public class BatchWordCount {
    public static void main(String[] args) throws Exception {
        /**
         * 实现步骤:
         * 1)初始化flink批处理的运行环境
         * 2)指定文件路径,获取文件数据
         * 3)对获取到的数据进行空格拆分
         * 4)对拆分的单词进行计数,每个单词记一次数
         * 5)对相同的单词进行分组操作
         * 6)对分组后的数据进行累加操作
         * 7)打印输出(测试)
         * 8)启动作业,递交任务
         */
        //初始化flink批处理的运行环境(获取到当前环境,如果本地运行获取local环境)
        final ExecutionEnvironment env = ExecutionEnvironment.getExecutionEnvironment();

        //指定文件路径,获取文件数据
        final DataSource<String> lines = env.readTextFile("./data/input/wordcount.txt");

        //对获取到的数据进行空格拆分
        //map与flatmap的区别
        //String:传入值类型
        //String:返回值类型
        /**
         * hello world
         * hello flink
         * hello scala
         * hello spark
         */
        final FlatMapOperator<String, String> words = lines.flatMap(new FlatMapFunction<String, String>() {
            @Override
            public void flatMap(String line, Collector<String> out) throws Exception {
                //将每行字符串进行空格拆分
                final String[] dataArray = line.split(" ");
                //循环遍历字符串数组
                for (String word : dataArray) {
                    //需要使用out进行返回数据
                    out.collect(word);
                }
            }
        });

        /**
         * 对拆分的单词进行计数,每个单词记一次数
         * String:传入值类型
         * Tuple2<String, Integer>:返回值类型<单词, 单词次数>
         * 元祖对象最长可以传递25个参数,Tuple1 -> Tuple25, TupleN->N表示参数的个数
         */
        final MapOperator<String, Tuple2<String, Integer>> wordAndOne = words.map(new MapFunction<String, Tuple2<String, Integer>>() {
            @Override
            public Tuple2<String, Integer> map(String value) throws Exception {
                return Tuple2.of(value, 1);
            }
        });

        //对相同的单词进行分组操作
        final UnsortedGrouping<Tuple2<String, Integer>> grouped = wordAndOne.groupBy(0);

        //对分组后的数据进行累加操作
        final AggregateOperator<Tuple2<String, Integer>> summed = grouped.sum(1);

        //打印输出(测试)
        summed.print();

        //todo 8)启动作业,递交任务
        //在批处理开发中以下方法会触发作业的递交操作,故无需 env.execute()
        //'execute()', 'count()', 'collect()', or 'print()'.
        //env.execute();
    }
}

  • 以流处理的方式读取socket里面的数据
package com.hmi1024.flink.example;

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.common.functions.MapFunction;
import org.apache.flink.api.java.tuple.Tuple;
import org.apache.flink.api.java.tuple.Tuple2;
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;
import org.apache.flink.util.Collector;

/**
 * 使用流的方式进行单词统计
 * 读取socket里面的数据,对单词进行空格拆分,对每个单词进行计算,然后进行分组(分流)累加
 *
 * 流作业与批作业的区别:
 * 1:批作业需要数据事先存在,流作业数据事先可以不存在
 * 2:批作业数据是有界的,流作业的数据是无界
 * 3:批处理作业运行完成作业停止,流作业不会主动停止
 */
public class StreamWordCount {
    public static void main(String[] args) throws Exception {
        /**
         * 实现步骤:
         * 1)初始化flink流处理的运行环境
         * 2)指定socket数据源,获取数据
         * 3)对获取到的数据进行空格拆分
         * 4)对拆分的单词进行计数,每个单词记一次数
         * 5)对相同的单词进行分组操作
         * 6)对分组后的数据进行累加操作
         * 7)打印输出(测试)
         * 8)启动作业,递交任务
         */
        //初始化flink流处理的运行环境
        final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        
		//设置并行度
        env.setParallelism(2);

        //指定socket数据源,获取数据
        final DataStreamSource<String> socketTextStream = env.socketTextStream("node1", 9999);

        //对获取到的数据进行空格拆分
        final SingleOutputStreamOperator<String> words = socketTextStream.flatMap(
                new FlatMapFunction<String, String>() {
            @Override
            public void flatMap(String line, Collector<String> out) throws Exception {
                //将每行字符串进行空格拆分
                final String[] dataArray = line.split(" ");
                //循环遍历字符串数组
                for (String word : dataArray) {
                    //需要使用out进行返回数据
                    out.collect(word);
                }
            }
        });
        
        //对拆分的单词进行计数,每个单词记一次数
        final SingleOutputStreamOperator<Tuple2<String, Integer>> wordAndOne = words.map(
                new MapFunction<String, Tuple2<String, Integer>>() {
            @Override
            public Tuple2<String, Integer> map(String value) throws Exception {
                return Tuple2.of(value, 1);
            }
        });

        //对相同的单词进行分组操作
        final KeyedStream<Tuple2<String, Integer>, Tuple> keyedStream = wordAndOne.keyBy(0);

        //对分组后的数据进行累加操作
        final SingleOutputStreamOperator<Tuple2<String, Integer>> summed = keyedStream.sum(1);

        //打印输出(测试)
        summed.print();

        //启动作业,递交任务
        env.execute();
    }
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值