7.Flink数据流API编程指南-上

目录

概述

Flink中的数据流程序是在数据流上实现转换的常规程序(例如,过滤,更新状态,定义窗口,聚合)。数据流由(例如,消息队列、套接字流、文件)创建的。结果通过接收器返回,例如,接收器可以将数据写入文件或标准输出(例如命令行终端)。Flink程序可以在各种上下文中运行,可以独立运行,也可以嵌入到其他程序中。可以在本地的 jvm 中执行,也可以在多台机器组成的集群中执行。

什么是 DataStream

DataStream API 的名称来自用于表示Flink程序中的数据集合的特殊 DataStream 类。可以将它们视为包含重复项的不可变数据集合。这些数据可以是有界的,也可以是无界的,用于处理它们的 API 是相同的,即流批一体的概念。

在使用方面,数据流与常规Java Collection类似,但在一些关键方面有很大不同。它们是不可变的,一旦创建了它们,就不能添加或删除元素。不仅遍历其中的元素,还可以使用DataStream API操作(也称为转换)对它们进行处理。

可以通过在Flink程序中添加源来创建初始数据流。然后,可以从中派生新的流,并通过使用map、filter等API方法将它们组合起来。

Flink常规编程规范

Flink程序是转换数据流的常规程序。每个程序都由相同的基本部分组成:

  • 1,获取执行环境;
  • 2.加载/创建初始数据,
  • 3.指定对该数据的转换,
  • 4.指定把计算结果存放在哪里,
  • 5.触发程序执行

现在,将对这些步骤进行概述,有关详细信息,请参阅相应的部分。注意,Java DataStream API的所有核心类都可以在 org.apache.flink.streaming.api 中找到。

StreamExecutionEnvironment是所有Flink程序的基础。你可以在StreamExecutionEnvironment上使用这些静态方法获得一个:

java 复制代码
getExecutionEnvironment();

createLocalEnvironment();

createRemoteEnvironment(String host, int port, String... jarFiles);

通常,只需要使用 getExecutionEnvironment() ,因为它将根据上下文做出正确选择:如果在IDE中执行程序或作为常规Java程序,它将创建一个本地环境,将在本地机器上执行程序。如果将程序打包成一个JAR文件,并通过命令行调用它,那么Flink集群管理器将执行程序的主方法,getExecutionEnvironment()将返回一个执行环境,用于在集群上执行程序。

为了指定数据源,执行环境有几种方法可以使用各种方法从文件中读取:可以将它们作为CSV文件逐行读取,也可以使用任何其他提供的源。要将文本文件作为行序列读取,可以使用:

java 复制代码
final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

DataStream<String> text = env.readTextFile("file:///path/to/file");

这将提供一个数据流,然后可以在其上应用转换以创建新的派生数据流。

通过调用带有转换函数的DataStream上的方法来应用转换。例如,一个map应用如下:

java 复制代码
DataStream<String> input = ...;

DataStream<Integer> parsed = input.map(new MapFunction<String, Integer>() {
    @Override
    public Integer map(String value) {
        return Integer.parseInt(value);
    }
});

这将原始集合中的每个String转换为Integer来创建一个新的数据流。

一旦有了包含最终结果的数据流,就可以通过创建接收器将其写入外部系统。这些只是一些创建接收器的示例方法:

java 复制代码
writeAsText(String path);

print();

上面的步骤完成时,就需要通过调用StreamExecutionEnvironment上的execute()来触发程序执行。根据ExecutionEnvironment的类型,在自己的机器上执行,或者将程序提交到集群上执行。

execute()方法将等待作业完成,然后返回jobeexecutionresult,其中包含执行时间和累加器结果。

如果不想等待作业完成,可以通过调用StreamExecutionEnvironment上的executeAsync()来触发异步作业执行。它将返回一个JobClient,可以使用它与刚刚提交的作业进行通信。例如,下面是如何通过使用executeAsync()来实现execute()的语义。

java 复制代码
final JobClient jobClient = env.executeAsync();

final JobExecutionResult jobExecutionResult = jobClient.getJobExecutionResult().get();

关于程序执行的最后一部分对于理解何时以及如何执行Flink操作至关重要。所有Flink程序都是惰性执行的:当程序的main方法被执行时,数据加载和转换不会直接发生。相反,每个操作都被创建并添加到数据流图中。当执行环境中的execute()调用显式触发执行时,操作才会实际执行。程序是在本地执行还是在集群上执行取决于执行环境的类型。

惰性计算可以构建复杂的程序,Flink将这些程序作为一个整体规划单元执行。

编程案例

下面是一个Flink批处理案例,代表了Flink流批处理的基本流程。

java 复制代码
import org.apache.flink.streaming.api.environment.StreamExecutionEnvironment;
import org.apache.flink.streaming.api.datastream.DataStream;
import org.apache.flink.api.common.functions.FilterFunction;

public class Example {

    public static void main(String[] args) throws Exception {
        final StreamExecutionEnvironment env =
                StreamExecutionEnvironment.getExecutionEnvironment();

        DataStream<Person> flintstones = env.fromElements(
                new Person("Fred", 35),
                new Person("Wilma", 35),
                new Person("Pebbles", 2));

        DataStream<Person> adults = flintstones.filter(new FilterFunction<Person>() {
            @Override
            public boolean filter(Person person) throws Exception {
                return person.age >= 18;
            }
        });

        adults.print();

        env.execute();
    }

    public static class Person {
        public String name;
        public Integer age;

        public Person(String name, Integer age) {
            this.name = name;
            this.age = age;
        }

        public String toString() {
            return this.name + ": age " + this.age.toString();
        }
    }
}

数据源

源是程序读取输入的地方。可以使用 StreamExecutionEnvironment.addSource(sourceFunction) 将源附加到程序中。Flink附带了许多预实现的源代码函数,可以通过为非并行源代码实现 SourceFunction ,或者通过实现 ParallelSourceFunction 接口或为并行源代码扩展 RichParallelSourceFunction 来编写自己的自定义源代码。

有几个预定义的流源可以从 StreamExecutionEnvironment 中访问

基于文件

  • readTextFile(path) -逐行读取文本文件,即遵守TextInputFormat规范的文件,并将其作为字符串返回。
  • readFile(fileInputFormat, path) -按照指定的文件输入格式读取(一次)文件。
  • readFile(fileInputFormat, path, watchType, interval, pathFilter, typeInfo) -这是前两个方法在内部调用的方法。它根据给定的fileInputFormat读取路径中的文件。根据所提供的watchType,这个源可以定期(每隔毫秒)监视新数据的路径(fileprocessingmode . process_continuous),或者处理一次当前路径中的数据并退出(FileProcessingMode.PROCESS_ONCE)。使用pathFilter,用户可以进一步排除正在处理的文件。

Socket-based

socketTextStream - 从 socket 中读取,元素之间使用分隔器

Collection-based:

fromCollection(Collection) - 通过Java Java.util.Collection创建数据流,所有集合中的元素是同一种类型。

fromCollection(Iterator, Class) - 通过iterator创建数据流,通过 Class 指定返回 iterator 返回数据的类型

fromElements(T ...) - Creates a data stream from the given sequence of objects. All objects must be of the same type.

fromParallelCollection(SplittableIterator, Class) - Creates a data stream from an iterator, in parallel. The class specifies the data type of the elements returned by the iterator.

fromSequence(from, to) - Generates the sequence of numbers in the given interval, in parallel.

自定义

结束

下部分在下一篇中补充。

相关推荐
W Y3 小时前
【架构-37】Spark和Flink
架构·flink·spark
ycsdn103 小时前
Caused by: org.apache.flink.api.common.io.ParseException: Row too short:
大数据·flink
晨航1 天前
Flink本地模式安装详解
大数据·flink
sf_www1 天前
flink 内存配置(五):网络缓存调优
大数据·网络·flink
我的K84091 天前
Flink滑动窗口(Sliding)中window和windowAll的区别
flink
inori12561 天前
FlinkSql读取外部Mysql和HBase数据库的方法(scala)
mysql·flink·hbase
小强签名设计2 天前
Flink CDC 同步 Mysql 数据
大数据·mysql·flink
牧竹子2 天前
FLINK单机版安装部署入门-1
大数据·flink
sf_www2 天前
flink 内存配置(四):内存调优和问题处理
大数据·flink
静听山水2 天前
Flink-Kafka-Connector
flink