Flink DataStream 编程入门

流处理是 Flink 的核心,流处理的数据集用 DataStream 表示。数据流从能够从各类各样的数据源中建立(消息队列、Socket 和 文件等),通过 DataStream 的各类 transform 操做,最终输出文件或者标准输出。这个过程跟以前文章中介绍的 Flink 程序基本骨架同样。本篇介绍 DataStream 相关的入门知识。java

Flink 101

为了学习 Flink 的朋友能查看到每一个例子的源码,我建立了一个 GitHub 项目:https://github.com/duma-repo/awesome-flink 这里会存放每一篇文章比较重要的示例的源码,目前支持 Java 和 Scala,仍在不断完善中。代码下载后能够在本地运行,也能够打包放在集群上运行。同时,欢迎各位将优质的资源提交到项目中。
git

简单示例

import org.apache.flink.api.common.functions.FlatMapFunction;
import org.apache.flink.api.java.tuple.Tuple2;
import org.apache.flink.streaming.api.datastream.DataStream;
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 WindowWordCount {

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

        StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

        DataStream<Tuple2<String, Integer>> dataStream = env
                .socketTextStream("localhost", 9999)
                .flatMap(new Splitter())
                .keyBy(0)
                .timeWindow(Time.seconds(5))
                .sum(1);

        dataStream.print();

        env.execute("Window WordCount");
    }

    public static class Splitter implements FlatMapFunction<String, Tuple2<String, Integer>> {
        @Override
        public void flatMap(String sentence, Collector<Tuple2<String, Integer>> out) throws Exception {
            for (String word: sentence.split(" ")) {
                out.collect(new Tuple2<String, Integer>(word, 1)); //空格分割后,每一个单词转换成 (word, 1) 二元组输出
            }
        }
    }

}

这个例子跟之间介绍 WordCount 的例子相似,这里详细介绍下涉及的 API 和含义github

  • 数据源:socketTextStream 是从 socket 建立的数据流,可使用 nc -l 9000 建立 socket 客户端发送数据
  • transform:flatMap 将输入的数据按照空格分割后,扁平化处理(flat即为扁平的意思);keyBy 会按照指定的 key 进行分组,这里就是将单词做为 key;timeWindow 指定时间窗口,这里是 5s 处理一次;sum 是聚合函数,将分组好的单词个数求和
  • 输出:print 将处理完的数据输出到标准输出流中,能够在控制台看到输出的结果。调用 execute 方法提交 Job

Data Source

通过以上的介绍,咱们知道常见的数据源有 socket、消息队列和文件等。对于常见的数据源 Flink 已经定义好了读取函数,接下来一一介绍。apache

基于文件

  • readTextFile(path):读文本文件,默认是文件类型是 TextInputFormat,而且返回类型是 String
  • readFile(fileInputFormat, path):读文件,须要指定输入文件的格式
  • readFile(fileInputFormat, path, watchType, interval, typeInfo):以上两个方法内部都会调用这个方法,参数说明:
    •  fileInputFormat - 输入文件的类型
    •  path - 输入文件路径
    •  watchType - 取值为 FileProcessingMode.PROCESS_CONTINUOUSLY 和 FileProcessingMode.PROCESS_ONCE
      • FileProcessingMode.PROCESS_CONTINUOUSLY - 当输入路径下有文件被修改,整个路径下内容将会被从新处理
      • FileProcessingMode.PROCESS_ONCE - 只扫描一次,便退出。所以这种模式下输入数据只读取一次
    •  interval - 依赖 watchType 参数,对于 FileProcessingMode.PROCESS_CONTINUOUSLY 每隔固定时间(单位:毫秒)检测路径下是否有新数据
    •  typeInfo - 返回数据的类型

须要注意,在底层 Flink 将读文件的过程分为两个子任务 —— 文件监控和数据读取(reader)。监控任务由 1 个 task 实现,而读取的任务由多个 task 实现,数量与 Job 的并行度相同。监控任务的做用是扫描输入路径(周期性或者只扫描一次,取决于 watchType),当数据能够被处理时,会将数据分割成多个分片,将分片分配给下游的 reader 。一个分片只会被一个 reader 读取,一个 reader 能够读取多个分片。编程

基于 Socket

  • socketTextStream:从 socket 数据流中读数据

基于 Collection

  • fromCollection(Collection):从 Java.util.Collection 类型的数据中建立输入流,collection 中的全部元素类型必须相同
  • fromCollection(Iterator, Class):从 iterator (迭代器)中建立输入流,Class 参数指定从 iterator 中的数据类型
  • fromElements(T ...):从给定的参数中建立输入流, 全部参数类型必须相同
  • fromParallelCollection(SplittableIterator, Class):从 iterator 中建立并行的输入流,Class 指定 iterator 中的数据类型
  • generateSequence(from, to):从 from 至 to 之间的数据序列建立并行的数据流

自定义

  • addSource:能够自定义输入源,经过实现 SourceFunction 接口来自定义非并行的输入流;也能够实现 ParallelSourceFunction 接口或集成 RichParallelSourceFunction 类来自定义并行输入流,固然也能够定义好的数据源,如:Kafka,addSource(new FlinkKafkaConsumer08<>(...))

DataStream 的 transform 

以前已经介绍了一些 transfrom 函数,如:map、flatMap 和 filter 等。同时还有窗口函数:window、timeWindow 等,聚合函数:sum、reduce 等。更多的 transform 函数以及使用将会单独写一篇文章介绍。api

Data Sink

Data Sink 即是数据的输出。同 Data Source 相似, Flink 也内置了一些输出函数,以下:socket

 

  • writeAsText(path) / TextOutputFormat:将数据做为 String 类型输出到指定文件
  • writeAsCsv(...) / CsvOutputFormat:将 Tuple 类型输出到 ',' 分隔的 csv 类型的文件。行和列的分隔符能够经过参数配置,默认的为 '\n' 和 ','
  • print() / printToErr():将数据打印到标准输出流或者标准错误流,能够指定打印的前缀。
  • writeUsingOutputFormat() / FileOutputFormat:输出到 OutputFormat 类型指定的文件,支持对象到字节的转换。
  • writeToSocket:根据 SerializationSchema 将数据输出到 socket 
  • addSink:自定义输出函数,如:自定义将数据输出到 Kafka

小结

本篇文章主要介绍了 Flink Streaming 编程的基本骨架。详细介绍了 Streaming 内置的 Data Source 和 DataSink 。下篇将继续介绍 Flink Streaming 编程涉及的基本概念。ide

代码地址: https://github.com/duma-repo/awesome-flink/blob/master/chapter-2-flink-streaming/2-1-streaming-starter.md函数

 

欢迎关注公众号「渡码」学习

 

相关文章
相关标签/搜索