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上使用这些静态方法获得一个:

getExecutionEnvironment();

createLocalEnvironment();

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

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

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

final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

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

  这将提供一个数据流,然后可以在其上应用转换以创建新的派生数据流。
通过调用带有转换函数的DataStream上的方法来应用转换。例如,一个map应用如下:

DataStream<String> input = ...;

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

  这将原始集合中的每个String转换为Integer来创建一个新的数据流。
一旦有了包含最终结果的数据流,就可以通过创建接收器将其写入外部系统。这些只是一些创建接收器的示例方法:

writeAsText(String path);

print();

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

  execute()方法将等待作业完成,然后返回jobeexecutionresult,其中包含执行时间和累加器结果。
如果不想等待作业完成,可以通过调用StreamExecutionEnvironment上的executeAsync()来触发异步作业执行。它将返回一个JobClient,可以使用它与刚刚提交的作业进行通信。例如,下面是如何通过使用executeAsync()来实现execute()的语义。

final JobClient jobClient = env.executeAsync();

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

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

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

编程案例

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

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.

自定义

结束

  下部分在下一篇中补充。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

流月up

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

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

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

打赏作者

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

抵扣说明:

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

余额充值