编程模型及核心概念

编程模型及核心概念

核心概念概述

Flink 程序是实现了分布式集合转换transformation(例如过滤filter映射mapping更新状态updating statejoin分组grouping定义窗口defining windows聚合aggregating)的规范化程序。集合初始创建自 sources(例如读取文件reading from fileskafka 主题kafka topics,或本地local内存memory中的集合)。结果通过 sink 返回,例如,它可以将数据写入(分布式)文件,或标准输出(例如命令行终端)。Flink 程序可以在多种环境中运行,独立运行或嵌入到其他程序中。可以在本地 JVM 中执行,也可以在多台机器的集群上执行。

针对有界和无界两种数据 source 类型,可以使用 DataSet API 来编写批处理程序或使用 DataStream API 来编写流处理程序。本篇指南将介绍这两种 API 通用的基本概念,关于使用 API 编写程序的具体信息请查阅 流处理指南批处理指南

大数据处理的流程

  • MapReduce: input -> map(reduce) -> output
  • Storm: input -> Spout(Bolt) -> output
  • Spark: input -> Transformation/action -> output
  • Spark: input -> Transformation/sink -> output

中间的部分每个框架都会在中间的过程进行自己的操作,但是大体的流程是一样的。

请注意: 当展示如何使用 API 的实际示例时我们使用 StreamingExecutionEnvironmentDataStream API。对于批处理,将他们替换为 ExecutionEnvironmentDataSet API 即可,概念是完全相同的。

DataSet&DataStream

Flink 用特有的 DataSetDataStream 类来表示程序中的数据。你可以将他们视为可能包含重复项不可变immutable数据集合。对于 DataSet,数据是有限的,而对于 DataStream,元素的数量可以是无限的。

这些集合与标准的 Java 集合有一些关键的区别。首先它们是不可变的,也就是说它们一旦被创建就不能添加或删除元素了。你也不能简单地检查它们内部的元素。

在 Flink 程序中,集合最初通过添加数据 source 来创建,通过使用诸如 mapfilter 等 API 方法对数据 source 进行转换从而派生新的集合。

Flink编程模型(剖析一个 Flink 程序)

Flink 程序看起来像是转换数据集合的规范化程序。每个程序由一些基本的部分组成:

  1. 获取执行环境;
  2. 加载/创建初始数据;
  3. 指定对数据的转换操作;transformation
  4. 指定计算结果存放的位置;sink
  5. 触发程序执行;

Java

我们现在将概述每个步骤,详细信息请参阅相应章节。请注意所有 Java DataSet API 的核心类可以在这个包 org.apache.flink.api.java 中找到,同时 Java DataStream API 可以在这个包 org.apache.flink.streaming.api 中找到。

StreamExecutionEnvironment 是所有 Flink 程序的基础。你可以使用它的这些静态方法获取:

getExecutionEnvironment()

createLocalEnvironment()

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

通常你只需要使用 getExecutionEnvironment(),因为它会根据上下文环境完成正确的工作:如果你在 IDE 中执行程序或者作为标准的 Java 程序来执行,它会创建你的本机执行环境;如果你将程序封装成 JAR 包,然后通过命令行调用,Flink 集群管理器会执行你的 main 方法并且 getExecutionEnvironment() 会返回在集群上执行程序的执行环境。

针对不同的数据 source,执行环境有若干不同读取文件的方法:你可以逐行读取 CSV 文件,或者使用完全自定义的输入格式。要将文本文件作为一系列行读取,你可以使用:

final StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

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

这样你会得到一个 DataStream 然后对其应用转换操作从而创建新的派生 DataStream。

通过调用 DataStream 的转换函数来进行转换。下面是一个映射转换的实例:

DataStream<String> input = ...;

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

这会通过把原始数据集合的每个字符串转换为一个整数创建一个新的 DataStream。

一旦你得到了包含最终结果的 DataStream,就可以通过创建 sink 将其写入外部系统。如下是一些创建 sink 的示例:

writeAsText(String path)

print()

当设定好整个程序以后你需要调用 StreamExecutionEnvironmentexecute() 方法触发程序执行。至于在你的本机触发还是提交到集群运行取决于 ExecutionEnvironment 的类型。

execute() 方法返回 JobExecutionResult,它包括执行耗时和一个累加器的结果。

如果你不需要等待作业的结束,只是想要触发程序执行,你可以调用 StreamExecutionEnvironmentexecuteAsync() 方法。这个方法将返回一个 JobClient 对象,通过 JobClient 能够与程序对应的作业进行交互。作为例子,这里介绍通过 executeAsync() 实现与 execute() 相同行为的方法。

final JobClient jobClient = env.executeAsync();

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

有关流数据的 source 和 sink 以及有关 DataStream 支持的转换操作的详细信息请参阅流处理指南

有关批数据的 source 和 sink 以及有关 DataSet 支持的转换操作的详细信息请参阅批处理指南

Scala

我们现在将概述每个步骤,详细信息请参阅相应章节。请注意所有 Scala DataSet API 可以在这个包 org.apache.flink.api.scala 中找到,同时,所有 Scala DataStream API 可以在这个包 org.apache.flink.streaming.api.scala 中找到。

StreamExecutionEnvironment 是所有 Flink 程序的基础。你可以使用它的这些静态方法获取:

getExecutionEnvironment() 直接获取

createLocalEnvironment() 创建本地的方式获取

createRemoteEnvironment(host: String, port: Int, jarFiles: String*) 创建远程的环境

通常只需要使用 getExecutionEnvironment(),因为它会根据上下文环境完成正确的工作,如果你在 IDE 中执行程序或者作为标准的 Java 程序来执行,它会创建你的本机执行环境。如果你将程序封装成 JAR 包,然后通过命令行调用,Flink 集群管理器会执行你的 main 方法并且 getExecutionEnvironment() 会返回在集群上执行程序的执行环境。

针对不同的数据 source,执行环境有若干不同的读取文件的方法:你可以逐行读取 CSV 文件,或者使用完全自定义的输入格式。要将文本文件作为一系列行读取,你可以使用:

val env = StreamExecutionEnvironment.getExecutionEnvironment()

val text: DataStream[String] = env.readTextFile("file:///path/to/file")

如此你会得到一个 DataStream 然后对其应用转换操作从而创建新的派生 DataStream。

通过调用 DataStream 的转换函数来进行转换。下面是一个映射转换的实例:

val input: DataSet[String] = ...

val mapped = input.map {
    x => x.toInt }

这会通过把原始数据集合的每个字符串转换为一个整数创建一个新的 DataStream。

一旦你得到了包含最终结果的 DataStream,就可以通过创建 sink 将其写入外部系统。如下是一些创建 sink 的示例:

writeAsText(path: String)

print()

当设定好整个程序以后你需要调用 StreamExecutionEnvironmentexecute() 方法触发程序执行。至于在你的本机触发还是提交到集群运行取决于 ExecutionEnvironment 的类型。

execute() 方法返回 JobExecutionResult,它包括执行耗时和一个累加器的结果。

如果你不需要等待作业的结束,只是想要触发程序执行,你可以调用 StreamExecutionEnvironmentexecuteAsync() 方法。这个方法将返回一个 JobClient 对象,通过 JobClient 能够与程序对应的作业进行交互。作为例子,这里介绍通过 executeAsync() 实现与 execute() 相同行为的方法。


                
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值