概述

Apache Flink是一个面向分布式数据流处理和批量数据处理的开源计算平台,它能够基于同一个Flink运行时,提供支持流处理和批处理两种类型应用的功能。

现有的开源计算方案,会把流处理和批处理作为两种不同的应用类型,因为它们所提供的SLA(Service-Level-Aggreement)是完全不相同的:

流处理一般需要支持低延迟、Exactly-once保证,而批处理需要支持高吞吐、高效处理。

Flink从另一个视角看待流处理和批处理,将二者统一起来:Flink是完全支持流处理,也就是说作为流处理看待时输入数据流是无界的;

批处理被作为一种特殊的流处理,只是它的输入数据流被定义为有界的。

流处理特点

  1. 支持高吞吐、低延迟、高性能的流处理
  2. 支持带有事件时间的窗口(Window)操作
  3. 支持有状态计算的Exactly-once语义
  4. 支持高度灵活的窗口(Window)操作,支持基于time、count、session,以及data-driven的窗口操作
  5. 支持具有Backpressure功能的持续流模型
  6. 支持基于轻量级分布式快照(Snapshot)实现的容错
  7. 一个运行时同时支持Batch on Streaming处理和Streaming处理
  8. Flink在JVM内部实现了自己的内存管理
  9. 支持迭代计算
  10. 支持程序自动优化:避免特定情况下Shuffle、排序等昂贵操作,中间结果有必要进行缓存

Flink 中的 API

批处理 flink和spark的区别 flink批处理性能_flink


这里介绍我们常用的DataStream API:

Flink API 第二层抽象是 Core APIs。实际上,许多应用程序不需要使用到上述最底层抽象的 API,而是可以使用 Core APIs 进行编程:其中包含 DataStream API(应用于有界/无界数据流场景)和 DataSet API(应用于有界数据集场景)两部分。Core APIs 提供的流式 API(Fluent API)为数据处理提供了通用的模块组件,例如各种形式的用户自定义转换(transformations)、联接(joins)、聚合(aggregations)、窗口(windows)和状态(state)操作等。此层 API 中处理的数据类型在每种编程语言中都有其对应的类。

DataStream API

DataStream API 得名于特殊的 DataStream 类,该类用于表示 Flink 程序中的数据集合。你可以认为 它们是可以包含重复项的不可变数据集合。这些数据可以是有界(有限)的,也可以是无界(无限)的,但用于处理它们的API是相同的。

Flink 程序看起来像一个转换 DataStream 的常规程序。每个程序由相同的基本部分组成:

  1. 获取一个执行环境(execution environment);
  2. 加载/创建初始数据;
  3. 指定数据相关的转换;
  4. 指定计算结果的存储位置;
  5. 触发程序执行。

获取一个执行环境

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

StreamExecutionEnvironment env = StreamExecutionEnvironment.getExecutionEnvironment();

通常,你只需要使用 getExecutionEnvironment() 即可,因为该方法会根据上下文做正确的处理:如果你在 IDE 中执行你的程序或将其作为一般的 Java 程序执行,那么它将创建一个本地环境,该环境将在你的本地机器上执行你的程序。

加载/创建初始数据

为了指定 data sources,执行环境提供了一些方法,可以使用任何第三方提供的 source。
这里介绍使用最多的Flink提供的kafka连接器,加入下方依赖后及可使用。

<dependency>
    <groupId>org.apache.flink</groupId>
    <artifactId>flink-connector-kafka_2.11</artifactId>
    <version>1.14.3</version>
</dependency>
Properties properties = new Properties();
properties.setProperty("bootstrap.servers", "localhost:9092");
properties.setProperty("group.id", "test");
DataStream<String> stream = env
    .addSource(new FlinkKafkaConsumer<>("topic", new SimpleStringSchema(), properties));

同时也可以使用union合并多个流,新的流包含所有流的数据。

指定数据相关的转换

得到了 DataStream后,你可以在上面应用转换(transformation)来创建新的派生 DataStream。
你可以调用 DataStream 上具有转换功能的方法来应用转换。

指定计算结果的存储位置

一旦你有了包含最终结果的 DataStream,你就可以通过创建 sink 把它写到外部系统。

触发程序执行

一旦指定了完整的程序,需要调用 StreamExecutionEnvironment 的 execute() 方法来触发程序执行。根据 ExecutionEnvironment 的类型,执行会在你的本地机器上触发,或将你的程序提交到某个集群上执行。