什么是Flink

Apache Flink 是一个开源的分布式,高性能,高可用,准确的流处理框架。
分布式:表示flink程序可以运行在很多台机器上,
高性能:表示Flink处理性能比较高
高可用:表示flink支持程序的自动重启机制。
准确的:表示flink可以保证处理数据的准确性。
Flink支持流处理和批处理,虽然我们刚才说了flink是一个流处理框架,但是它也支持批处理
其实对于flink而言,它是一个流处理框架,批处理只是流处理的一个极限特例而已。

看一下这张图,
image.png
左边是数据源,从这里面可以看出来,这些数据是实时产生的一些日志,或者是数据库、文件系统、kv存储系统中的数据。
中间是Flink,负责对数据进行处理。
右边是目的地,Flink可以将计算好的数据输出到其它应用中,或者存储系统中。

Flink发展史

版本发布时间参考GitHub: https://github.com/apache/flink/releases

  • 2008:柏林理工大学的一个研究性项目Stratosphere
  • 2014-04:Stratosphere贡献给Apache基金会,成为Apache的孵化项目
  • 2014-12:成为Apache顶级项目
  • 18 Jun 2015:发布0.9版本(第一个稳定版本)
  • 3 Mar 2016:Flink 1.0.0
  • 3 Aug 2016:Flink 1.1.0
  • 30 Jan 2017:Flink 1.2.0;
  • 26 May 2017:Flink 1.3.0;
  • 12 Dec 2017:Flink 1.4.0;
  • 26 May 2018:Flink 1.5.0;
  • 9 Aug 2018:Flink 1.6.0;
  • 30 Nov 2018:Flink 1.7.0;
  • 2019年1月8日,阿里巴巴以9000万欧元收购该公司!
  • 9 Apr 2019:Flink 1.8.0
  • 22 Aug 2019:Flink 1.9.0
  • 11 Feb 2020:Flink 1.10.0
  • 6 Jul 2020:Flink 1.11.0
  • 7 Dec 2020:Flink 1.12.0
  • Apr 2021:Flink 1.13.0

    Flink的特点

  • 支持Scala和Java API

  • 支持批流一体
  • 同时支持高吞吐、低延迟、高性能
  • 支持事件时间和处理时间语义,基于事件时间语义能够针对无序事件提供精确、一致的结果;基于处理时间语义能够用在具有极低延迟需求的应用中
  • 支持不同时间语义下的窗口编程
  • 支持有状态计算
  • 支持具有Backpressure功能的持续流模型
  • 提供精确一次(exactly once)的状态一致性保障
  • Flink在JVM内部实现了自己的内存管理
  • 基于轻量级的分布式快照CheckPoint的容错
  • 支持SavePoint机制,手工触发,适用于升级
  • 支持高可用性配置(无单点失效),与k8s、Yarn、Apache Mesos紧密集成。
  • 提供常见存储系统的连接器:Kafka,Elasticsearch等
  • 提供详细、可自由定制的系统及应用指标(metrics)集合,用于提前定位和响应问题

    Flink架构图

    image.png
API和类库 主要有两大块API,DataStream APIDataSet API,分别做流处理和批处理。
针对DataStream API这块,支持复杂事件处理,和table操作,其实也是支持SQL操作的。
针对DatasetAPI 这块,支持flinkML机器学习,Gelly图计算,table操作,这块也是支持SQL操作的。
Core flink的核心,分布式的流处理引擎。
Deploy 最下面表示是flink的部署模式,支持local,和集群(standalone,yarn),也支持在云上部署。

其实从这可以看出来,Flink也是有自己的生态圈的,里面包含了实时计算、离线计算、机器学习、图计算、Table和SQL计算等等
所以说它和Spark还是有点像的,不过它们两个的底层计算引擎是有本质区别的,一会我们会详细分析。

Flink三大核心组件

image.png

Data Source

数据源(负责接收数据),

Transformations

算子(负责对数据进行处理)

Data Sink

输出组件(负责把计算好的数据输出到其它存储介质中)

批处理和流处理

批处理:处理离线数据,冷数据。单个处理数据量大,处理速度比流慢。
流处理:在线,实时产生的数据。单次处理的数据量小,但处理速度更快。

  • 在大数据处理领域,批处理和流处理一般被认为是两种不同的任务,一个大数据框架一般会被设计为只能处理其中一种任务

例如Storm只支持流处理任务,而MapReduce、Spark只支持批处理任务。
Spark Streaming是Spark之上支持流处理任务的子系统,看似是一个特例,其实并不是——Spark Streaming采用了一种micro-batch的架构,就是把输入的数据流切分成细粒度的batch,并为每一个batch提交一个批处理的Spark任务,所以Spark Streaming本质上执行的还是批处理任务,和Storm这种流式的数据处理方式是完全不同的。

Flink通过灵活的执行引擎,能够同时支持批处理和流处理

在执行引擎这一层,流处理系统与批处理系统最大的不同在于节点之间的数据传输方式。

对于一个流处理系统,其节点间数据传输的标准模型是:当一条数据被处理完成后,序列化到缓存中,然后立刻通过网络传输到下一个节点,由下一个节点继续处理
这就是典型的一条一条处理

对于一个批处理系统,其节点间数据传输的标准模型是:当一条数据被处理完成后,序列化到缓存中,并不会立刻通过网络传输到下一个节点,当缓存写满的时候,就持久化到本地硬盘上,当所有数据都被处理完成后,才开始将处理后的数据通过网络传输到下一个节点

这两种数据传输模式是两个极端,对应的是流处理系统对低延迟的要求和批处理系统对高吞吐量的要求 Flink的执行引擎采用了一种十分灵活的方式,同时支持了这两种数据传输模型

Flink以固定的缓存块为单位进行网络数据传输,用户可以通过缓存块超时值指定缓存块的传输时机。如果缓存块的超时值为0,则Flink的数据传输方式类似前面所说的流处理系统的标准模型,此时系统可以获得最低的处理延迟
如果缓存块的超时值为无限大,则Flink的数据传输方式类似前面所说的批处理系统的标准模型,此时系统可以获得最高的吞吐量
这样就比较灵活了,其实底层还是流式计算模型,批处理只是一个极限特例而已。

看一下这个图中显示的三种数据传输模型
image.png
第一个:一条一条处理
第二个:一批一批处理
第三个:按照缓存块进行处理,缓存块可以无限小,也可以无限大,这样就可以同时支持流处理和批处理了。

Storm vs SparkStreaming vs Flink

接下来我们来对比一下目前大数据领域中的三种实时计算引擎

产品 Storm SparkStreaming Flink
模型 Native Mirco-Batching Native
API 组合式 声明式 声明式
语义 At-least-once Exectly-once Exectly-once
容错机制 Ack Checkpoint Checkpoint
状态管理 基于DStream 基于操作
延时 Low Medium Low
吞吐量 Low High High

解释:
Native:表示来一条数据处理一条数据
Mirco-Batch:表示划分小批,一小批一小批的处理数据
组合式:表示是基础API,例如实现一个求和操作都需要写代码实现,比较麻烦,代码量会比较多。
声明式:表示提供的是封装后的高阶函数,例如filter、count等函数,可以直接使用,比较方便,代码量比较少。

Spark适合批处理,Spark Streaming本质上执行的还是批处理任务 Flink适合流处理,缓存块无限大→批处理

Spark和Flink的对比

两者最重要的区别(流和微批)

Micro Batching 模式(spark)

Micro-Batching 计算模式认为 “流是批的特例”, 流计算就是将连续不断的批进行持续计算,如果批足够小那么就有足够小的延时,在一定程度上满足了99%的实时计算场景。那么那1%为啥做不到呢?这就是架构的魅力,在Micro-Batching模式的架构实现上就有一个自然流数据流入系统进行攒批的过程,这在一定程度上就增加了延时。

Native Streaming 模式(flink)

Native Streaming 计算模式认为 “”批是流的特例”,这个认知更贴切流的概念,比如一些监控类的消息流,数据库操作的binlog,实时的支付交易信息等等自然流数据都是一条,一条的流入。Native Streaming 计算模式每条数据的到来都进行计算,这种计算模式显得更自然,并且延时性能达到更低。

实时计算框架如何选择

1:需要关注流数据是否需要进行状态管理
2:消息语义是否有特殊要求At-least-once或者Exectly-once
3:小型独立的项目,需要低延迟的场景,建议使用Storm
4:如果项目中已经使用了Spark,并且秒级别的实时处理可以满足需求,建议使用SparkStreaming
5:要求消息语义为Exectly-once,数据量较大,要求高吞吐低延迟,需要进行状态管理,建议选择Flink