flink DataStreamAPI流程概述
一个完整的flink程序,其执行流程主要包括:数据流输入 -> 转换(transformation) -> 数据流输出 三部分。数据流的起始是从各种源(例如消息队列、套接字流、文件)创建的,然后 DataStream 程序对数据流(例如过滤、更新状态、定义窗口、聚合)进行转换,最后通过 sink 返回,例如可以将数据写入文件或标准输出(例如命令行终端)。
DataStream 是什么
DataStream API 得名于特殊的 DataStream
类,该类用于表示 Flink 程序中的数据集合。你可以认为 它们是可以包含重复项的不可变数据集合。这些数据可以是有界(有限)的,也可以是无界(无限)的,但用于处理它们的API是相同的。
DataStream
在用法上类似于常规的 Java 集合
,但在某些关键方面却大不相同。它们是不可变的,这意味着一旦它们被创建,你就不能添加或删除元素。你也不能简单地察看内部元素,而只能使用 DataStream
API 操作来处理它们,DataStream
API 操作也叫作转换(transformation)。
浅尝flink流程:
接下来,通过写一个简单的demo来熟悉一下flink程序的流程。
首先先准备一个text文档,作为此次要处理的数据源
beef 5
chicken 2
potato 2
tomato 3
这里可以看到有两列数据,第一列是食物,第二列是一串数字(我们假设这是食物的价格),接下来我希望通过flink程序,将两组数据进行组合,输出: XXX价值XX元
flink程序代码:
public class Demo01 {
public static void main(String[] args) throws Exception {
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
String filePath = "D:\\JAVA\\code\\flink\\flink-practice\\flink-model-1\\src\\main\\resources\\demo1.txt";
DataStreamSource<String> dataStreamSource = env.readTextFile(filePath);
SingleOutputStreamOperator<String> map = dataStreamSource.map(new RichMapFunction<String, String>() {
@Override
public String map(String s) throws Exception {
String[] values = s.split(" ");
return values[0] + " 价值 :" + values[1] + " 元!";
}
});
map.print();
env.execute();
}
}
其输出结果为:
接下来我们简单的分析一下这段代码:
在这里插入图片描述
StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();
通过字面理解,我们可以看到这是在获取数据流的执行环境。StreamExecutionEnvironment
是所有 Flink 程序的基础,一般情况下StreamExecutionEnvironment
可以通过以下几种静态方法进行获取
getExecutionEnvironment()
createLocalEnvironment()
createRemoteEnvironment(String host, int port, String... jarFiles)
通常,你只需要使用 getExecutionEnvironment()
即可,因为该方法会根据上下文做正确的处理:如果你在 IDE 中执行你的程序或将其作为一般的 Java 程序执行,那么它将创建一个本地环境,该环境将在你的本地机器上执行你的程序。如果你基于程序创建了一个 JAR 文件,并通过命令行运行它,Flink 集群管理器将执行程序的 main 方法,同时 getExecutionEnvironment()
方法会返回一个执行环境以在集群上执行你的程序。
当我们通过 getExecutionEnvironment()
获取到流的执行环境后,接下来就是去指定data sources,执行环境提供了一些方法,支持使用各种方法从文件中读取数据:它支持直接逐行读取数据,像读 CSV 文件一样,或使用任何第三方提供的 source。如果我们只是将一个文本文件作为一个行的序列来读取,那么就可以使用readTextFile
:
String filePath = "D:\\JAVA\\code\\...\\src\\main\\resources\\demo1.txt";
DataStreamSource<String> dataStreamSource = env.readTextFile(filePath);
在拿到数据流(DataStream)之后,接下来的操作就是对数据流做转换(transformation),这里我们简单的使用了dataStream的map方法,其作用后续会详细解释,这里只要知道该方法是将数据源输入的数据转换成我们期望的数据就可以。
SingleOutputStreamOperator<String> map = dataStreamSource.map(new RichMapFunction<String, String>() {
@Override
public String map(String s) throws Exception {
String[] values = s.split(" ");
return values[0] + " 价值 :" + values[1] + " 元!";
}
});
在数据转换成功之后就是要将数据进行输出,print()
方法会将转换结果输出到控制台终端
map.print();
一旦指定了完整的程序,接下来就需要调用 StreamExecutionEnvironment
的 execute()
方法来触发程序执行。根据 ExecutionEnvironment
的类型,执行会在本地机器上触发,或是在提交到某个集群上执行。
execute()
方法将等待作业完成,然后返回一个 JobExecutionResult
,其中包含执行时间和累加器结果。
如果不想等待作业完成,可以通过调用 StreamExecutionEnvironment
的 executeAsync()
方法来触发作业异步执行。它会返回一个 JobClient
,可以通过它与刚刚提交的作业进行通信。
env.execute();
至此,一个完整的flink程序就完成了
eAsync()方法来触发作业异步执行。它会返回一个
JobClient`,可以通过它与刚刚提交的作业进行通信。
env.execute();
至此,一个完整的flink程序就完成了