从WordCount学习Flink源码-1

1.初识WordCount

        近几年实时数据处理和流式数据处理的框架Flink越来越火热,特别是这两年从Flink 1.13开始Flink做成了流批一体,他的火热程度就更不言而喻了。而我们学习Flink都是从WordCount开始的,WordCount对于现在的我们来说可能来说非常简单,但对初学者来说当时可能是我们噩梦的开始,特别是Flink的API名字相对来说都比较长,对于初学者的我们来说很容易把我们给烦死,于是我发明了这款防烦恼辅助器,设计非常的银杏,感到烦恼的小伙伴们可以对自己头上来一下就再也不会感到烦恼了(哈哈.....最近抖音刷多了,开个小玩笑)。

钉头锤_360百科

 下面我们再简单回顾一下WordCount的代码:

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
        DataStream<String> text = env.readTextFile("E:\\tmp\\hudi_flink\\src\\main\\resources\\a.txt");

        SingleOutputStreamOperator<Tuple2<String, Integer>> sumDS = text.map(new MapFunction<String, Tuple2<String, Integer>>() {
            @Override
            public Tuple2<String, Integer> map(String value) throws Exception {
                return new Tuple2<>(value, 1);
            }
        }).keyBy(new KeySelector<Tuple2<String, Integer>, String>() {
            @Override
            public String getKey(Tuple2<String, Integer> value) throws Exception {
                return value.f0;
            }
        }).sum(1);

        sumDS.print();


        env.execute();

 可以看到代码大概分为三部分:

1.第一部分是我们创建了一个StreamExecutionEnvironment,这个是flink的执行环境。

2.第二部分就是我们写的业务代码从env.readTextFlie到sumDS.print。

3.第三部分是env.execute方法

这三部分我们都耳熟能祥了,所有的flink代码基本也是由着三部分组成的,相信了解过Flink的兄弟们都知道Flink的算子分为,分为:source算子,转换算子,sink算子。

2.Source算子源码分析

source算子也有挺多种类例如:

env.readTextFile()

env.sockerTextStream()

env.fromCollection()

env.addSource()

看似很多,其实底层调用的都是env.addSource,所以我们自定义数据源的时候可以直接使用env.addSource,下面我们简单看一下env.readTextFile()底层的源码是如何调用的

 

 由于下面这个代码比较长,我们直接粘贴过来,可以看到里面除了校验参数,然后就是创建了一个监控函数,一个连续读文件算子的工厂,监控模式,最后调用了add.source方法。

 private <OUT> DataStreamSource<OUT> createFileInput(
            FileInputFormat<OUT> inputFormat,
            TypeInformation<OUT> typeInfo,
            String sourceName,
            FileProcessingMode monitoringMode,
            long interval) {

        Preconditions.checkNotNull(inputFormat, "Unspecified file input format.");
        Preconditions.checkNotNull(typeInfo, "Unspecified output type information.");
        Preconditions.checkNotNull(sourceName, "Unspecified name for the source.");
        Preconditions.checkNotNull(monitoringMode, "Unspecified monitoring mode.");

        Preconditions.checkArgument(
                monitoringMode.equals(FileProcessingMode.PROCESS_ONCE)
                        || interval >= ContinuousFileMonitoringFunction.MIN_MONITORING_INTERVAL,
                "The path monitoring interval cannot be less than "
                        + ContinuousFileMonitoringFunction.MIN_MONITORING_INTERVAL
                        + " ms.");

        ContinuousFileMonitoringFunction<OUT> monitoringFunction =
                new ContinuousFileMonitoringFunction<>(
                        inputFormat, monitoringMode, getParallelism(), interval);

        ContinuousFileReaderOperatorFactory<OUT, TimestampedFileInputSplit> factory =
                new ContinuousFileReaderOperatorFactory<>(inputFormat);

        final Boundedness boundedness =
                monitoringMode == FileProcessingMode.PROCESS_ONCE
                        ? Boundedness.BOUNDED
                        : Boundedness.CONTINUOUS_UNBOUNDED;

        SingleOutputStreamOperator<OUT> source =
                addSource(monitoringFunction, sourceName, null, boundedness)
                        .transform("Split Reader: " + sourceName, typeInfo, factory);

        return new DataStreamSource<>(source);
    }

3.转换算子源码分析

转换算子的种类非常丰富,像我们这个案例中我们就用到了map,sum算子。虽然我们flink也写了很多代码,但是我们有没有详细观察过这些算子底层是调用了那些方法,今天我们就一起来看看他的底层调用是怎么样的。

1.Map算子

 

 

从上面我们可以看到 map方法经过一系列的调用最终从function-->streamOperator-->transformation了,最终调用transformations.add方法。transformations是env的一个成员变量,是一个list集合,专门用来放transformation,至于他的作用我们后面再说。

2.sum算子

 sum算子从aggregate function --> reduce function --> transformation,最终还是调用transformations.add方法,其他算子我这边就不举例了,所有transform算子最终都是调用transformations.add方法,这样flink才可以从env中拿到我们作业的血缘依赖。

3.sink算子源码分析

1.Print算子

 

 print算子通过调用addSink -->  addOperator -->add 方法,最终也加入到了transformation中

 2.addSink算子

没想到addSink算子更简单,直接一步到位..

 

 好辣,今天就写这么多吧,明天继续写transformations获取到这些作业的血缘依赖该怎么处理把他交给flink来变成我们非常熟悉的streamGraph.

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Flink WordCountFlink 的一个经典示例,用于演示 Flink 流处理的基本功能。它是一个简单的单词计数程序,可以从输入文本中读取单词,并计算每个单词在文本中出现的次数。 以下是一个 Flink WordCount 的示例代码: ```java import org.apache.flink.api.java.utils.ParameterTool; import org.apache.flink.streaming.api.datastream.DataStream; import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment; import org.apache.flink.streaming.api.functions.source.FileSource; import org.apache.flink.streaming.api.functions.source.SourceFunction; import org.apache.flink.streaming.api.windowing.time.Time; public class WordCount { public static void main(String[] args) throws Exception { final ParameterTool params = ParameterTool.fromArgs(args); // 设置执行环境 final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment(); // 设置数据源 DataStream<String> text; if (params.has("input")) { text = env.readTextFile(params.get("input")); } else { System.out.println("Executing WordCount example with default input data set."); System.out.println("Use --input to specify file input."); text = env.fromElements(WordCountData.WORDS); } // 转换数据流 DataStream<WordWithCount> counts = text.flatMap(new Tokenizer()) .keyBy("word") .timeWindow(Time.seconds(5)) .sum("count"); // 输出结果 if (params.has("output")) { counts.writeAsText(params.get("output")); } else { System.out.println("Printing result to stdout. Use --output to specify output path."); counts.print(); } // 执行任务 env.execute("Streaming WordCount"); } // 单词拆分函数 public static final class Tokenizer implements FlatMapFunction<String, WordWithCount> { @Override public void flatMap(String value, Collector<WordWithCount> out) { String[] tokens = value.toLowerCase().split("\\W+"); for (String token : tokens) { if (token.length() > 0) { out.collect(new WordWithCount(token, 1L)); } } } } // 单词计数类 public static final class WordWithCount { public String word; public long count; public WordWithCount() {} public WordWithCount(String word, long count) { this.word = word; this.count = count; } @Override public String toString() { return word + " : " + count; } } } ``` 该程序使用 Flink 流处理 API 来读取输入文本、拆分单词、计数单词并输出结果。程序的具体执行流程如下: 1. 读取命令行参数或默认数据源。 2. 创建 Flink 执行环境。 3. 读取数据源。 4. 转换数据流,拆分单词并计数。 5. 输出结果到文件或标准输出。 6. 执行任务。 如果你想要运行 Flink WordCount 示例程序,可以按照以下步骤进行: 1. 下载 Flink 并解压。 2. 打开终端并进入 Flink 的安装目录。 3. 运行 `./bin/start-cluster.sh` 启动 Flink 集群。 4. 运行 `./bin/flink run examples/streaming/WordCount.jar --input /path/to/input/file --output /path/to/output/file`。 5. 等待程序执行完成,查看输出结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值