Flink简介
Apache Flink是一个框架和分布式处理引擎,用于对无限制和有限制的数据流进行有状态的计算。Flink被设计为可以在所有常见的集群环境中运行,以内存速度和任何规模执行计算。
在这里,我们解释Flink架构的重要方面。
1.处理无界和有界数据
任何类型的数据都是作为事件流产生的。信用卡交易,传感器测量,机器日志或网站或移动应用程序上的用户交互,所有这些数据都作为流生成。
数据可以作为无界流或有界流处理。
- 无界流有一个起点,但没有定义的终点。它们不会终止并在生成数据时提供数据。无限制的流必须被连续处理,即,事件被摄取后必须立即处理。无法等待所有输入数据到达,因为输入是无界的,并且在任何时间都不会完成。处理无限制的数据通常要求以特定顺序(例如事件发生的顺序)提取事件,以便能够推断出结果的完整性。
- 有界流具有定义的开始和结束。可以通过在执行任何计算之前提取所有数据来处理有界流。由于有界数据集始终可以排序,因此不需要有序摄取即可处理有界流。绑定流的处理也称为批处理。
Apache Flink擅长处理无边界和有边界的数据集。对时间和状态的精确控制使Flink的运行时能够在无限制的流上运行任何类型的应用程序。有界流由专门为固定大小的数据集设计的算法和数据结构在内部进行处理,从而产生出色的性能。
2.随处部署应用程序
Apache Flink是一个分布式系统,需要计算资源才能执行应用程序。Flink与所有常见的群集资源管理器(如Hadoop YARN,Apache Mesos和Kubernetes)集成,但也可以设置为作为独立群集运行。
Flink旨在与前面列出的每个资源管理器配合使用。这是通过特定于资源管理器的部署模式实现的,该模式允许Flink以其惯用方式与每个资源管理器进行交互。
部署Flink应用程序时,Flink会根据应用程序配置的并行性自动识别所需的资源,并向资源管理器请求它们。如果发生故障,Flink会通过请求新资源来替换发生故障的容器。提交或控制应用程序的所有通信均通过REST调用进行。这简化了Flink在许多环境中的集成。
3.任意规模运行应用程序
Flink旨在运行任何规模的有状态流应用程序。将应用程序并行化为可能在群集中分布并同时执行的数千个任务。因此,应用程序几乎可以利用无限数量的CPU,主内存,磁盘和网络IO。而且,Flink易于维护非常大的应用程序状态。它的异步和增量检查点算法可确保对处理延迟的影响最小,同时可保证一次Q状态一致性。
用户报告了其生产环境中运行的Flink应用程序的可伸缩性数字,例如
- 每天处理数万亿事件的应用程序,
- 维护多个TB状态的应用程序,以及
- 运行在数千个内核上的应用程序。
4.利用内存性能
有状态Flink应用程序针对本地状态访问进行了优化。任务状态始终保持在内存中,或者,如果状态大小超出可用内存,则始终保持在访问有效的磁盘数据结构中。因此,任务通过访问通常处于内存中的状态来执行所有计算,从而产生非常低的处理延迟。Flink通过定期将本地状态异步指向持久性存储来确保出现故障时一次准确的状态一致性。
Flink应用
Apache Flink 是一个针对无界和有界数据流进行有状态计算的框架。Flink 自底向上在不同的抽象级别提供了多种 API,并且针对常见的使用场景开发了专用的扩展库。
在本章中,我们将介绍 Flink 所提供的这些简单易用、易于表达的 API 和库。
1.流处理应用的基本组件
可以由流处理框架构建和执行的应用程序类型是由框架对 流、状态、时间 的支持程度来决定的。在下文中,我们将对上述这些流处理应用的基本组件逐一进行描述,并对 Flink 处理它们的方法进行细致剖析。
1.1.流
显而易见,(数据)流是流处理的基本要素。然而,流也拥有着多种特征。这些特征决定了流如何以及何时被处理。Flink 是一个能够处理任何类型数据流的强大处理框架。
- 有界 和 无界 的数据流:流可以是无界的;也可以是有界的,例如固定大小的数据集。Flink 在无界的数据流处理上拥有诸多功能强大的特性,同时也针对有界的数据流开发了专用的高效算子。
- 实时 和 历史记录 的数据流:所有的数据都是以流的方式产生,但用户通常会使用两种截然不同的方法处理数据。或是在数据生成时进行实时的处理;亦或是先将数据流持久化到存储系统中——例如文件系统或对象存储,然后再进行批处理。Flink 的应用能够同时支持处理实时以及历史记录数据流。
1.2.状态
只有在每一个单独的事件上进行转换操作的应用才不需要状态,换言之,每一个具有一定复杂度的流处理应用都是有状态的。任何运行基本业务逻辑的流处理应用都需要在一定时间内存储所接收的事件或中间结果,以供后续的某个时间点(例如收到下一个事件或者经过一段特定时间)进行访问并进行后续处理。
应用状态是 Flink 中的一等公民,Flink 提供了许多状态管理相关的特性支持,其中包括:
- 多种状态基础类型:Flink 为多种不同的数据结构提供了相对应的状态基础类型,例如原子值(value),列表(list)以及映射(map)。开发者可以基于处理函数对状态的访问方式,选择最高效、最适合的状态基础类型。
- 插件化的State Backend:State Backend 负责管理应用程序状态,并在需要的时候进行 checkpoint。Flink 支持多种 state backend,可以将状态存在内存或者 RocksDB。RocksDB 是一种高效的嵌入式、持久化键值存储引擎。Flink 也支持插件式的自定义 state backend 进行状态存储。
- 精确一次语义:Flink 的 checkpoint 和故障恢复算法保证了故障发生后应用状态的一致性。因此,Flink 能够在应用程序发生故障时,对应用程序透明,不造成正确性的影响。
- 超大数据量状态:Flink 能够利用其异步以及增量式的 checkpoint 算法,存储数 TB 级别的应用状态。
- 可弹性伸缩的应用:Flink 能够通过在更多或更少的工作节点上对状态进行重新分布,支持有状态应用的分布式的横向伸缩
1.3.时间
时间是流处理应用另一个重要的组成部分。因为事件总是在特定时间点发生,所以大多数的事件流都拥有事件本身所固有的时间语义。进一步而言,许多常见的流计算都基于时间语义,例如窗口聚合、会话计算、模式检测和基于时间的 join。流处理的一个重要方面是应用程序如何衡量时间,即区分事件时间(event-time)和处理时间(processing-time)。
Event-Time :事件时间是每个事件在其生产设备上发生的时间。此时间通常在进入Flink之前嵌入记录中,并且 可以从每个记录中提取该事件时间戳。
Ingestion-Time :摄取时间是事件进入Flink的时间。在源算子处,每个记录将源的当前时间作为时间戳,并且基于时间的 算子操作(如时间窗口)引用该时间戳。
Processing-Time : 处理时间是指执行相应算子操作的机器的系统时间。
Flink 提供了丰富的时间语义支持。
- 事件时间模式:使用事件时间语义的流处理应用根据事件本身自带的时间戳进行