1.支持流处理的引擎:Spark和Flink
Spark:基于批处理来模拟流的计算;
Flink:基于流计算来模拟批处理;
流式:只要数据一直在产生,计算就持续地进行
批处理:在预先定义的时间内运行计算,当计算完成时释放计算机资源
2.Flink概论:
不仅仅是高吞吐、低延迟的计算引擎,还提供很多高级功能:有状态的计算,支持状态管理,支持强一致性的数据语义,支持Event Time, WaterMark对消息乱序的处理。
四大基石:
- 强一致性——Checkpoint机制(见下)
- 托管状态(Managed state),并提供api (更方便调用和管理)
- watermark机制,解决基于事件事件处理时候的数据乱序和延迟的问题
-
流计算中计算一般都有基于窗口,Flink提供开箱即用的窗口操作,包括滚动窗口、滑动窗口、会话窗口,灵活的自定义窗口
2.1.Flink强一致性原理——Chandy-Lamport算法
把流计算看成是一个流式的拓扑,定期从拓扑的头部source点开始插入特殊的barriers,从上游开始不断的向下游广播这个barriers。每个节点收到这个barriers,会将state做一次快照,当每个节点都做完snapshot后,整个拓扑就算完整的做完一次Checkpoint。(分布式一致性完成)接下来不管出现任何故障,都会从最近的 Checkpoint进行恢复。
exactly-once的语义是基于分布式一致性快照做的。
有状态的Flink应用程序针对本地状态访问进行了优化。任务状态始终驻留在内存中,或者,如果状态大小超过可用内存,则保存在访问高效的磁盘上的数据结构中
3.实时计算场景
3.1实时数据存储
实时数据存储的时候做一些微聚合、过滤某些字段、数据脱敏,组建数据仓库,实时 ETL。
3.2实时数据分析
实时数据接入机器学习框架(TensorFlow)或者一些算法进行数据建模、分析,然后动态的给出商品推荐、广告推荐
3.3实时监控告警
金融相关涉及交易、实时风控、车流量预警、服务器监控告警、应用日志告警
3.4实时数据报表
活动营销时销售额/销售量大屏,TopN 商品
4.实时计算的挑战
4.1 数据处理唯一性
如何保证数据只处理一次?至少一次?最多一次?
4.2数据处理的及时性
采集的实时数据量太大的话可能会导致短时间内处理不过来,如何保证数据能够及时的处理,不出现数据堆积?
4.3 数据处理层和存储层的可扩展性
如何根据采集的实时数据量的大小提供动态扩缩容?
4.4数据处理层和存储层的容错性
如何保证数据处理层和存储层高可用,出现故障时数据处理层和存储层服务依旧可用?
5. Flink架构
从下至上:
1、部署:Flink 支持本地运行(IDE 中直接运行程序)、能在独立集群(Standalone 模式)或者在被 YARN、Mesos、K8s 管理的集群上运行,也能部署在云上。
2、运行:Flink 的核心是分布式流式数据引擎,意味着数据以一次一个事件的形式被处理。
3、API:DataStream、DataSet、Table、SQL API。
4、扩展库:Flink 还包括用于 CEP(复杂事件处理)、机器学习、图形处理等场景。
6.Flink 分布式运行
Flink 作业提交架构流程可见下图:
1、Program Code:我们编写的 Flink 应用程序代码
2、Job Client:Job Client 不是 Flink 程序执行的内部部分,但它是任务执行的起点。 Job Client 负责接受用户的程序代码,然后创建数据流,将数据流提交给 Job Manager 以便进一步执行。 执行完成后,Job Client 将结果返回给用户
3、Job Manager:主进程(也称为作业管理器)协调和管理程序的执行。 它的主要职责包括安排任务,管理 checkpoint ,故障恢复等。机器集群中至少要有一个 master,master 负责调度 task,协调 checkpoints 和容灾,高可用设置的话可以有多个 master,但要保证一个是 leader, 其他是 standby; Job Manager 包含 Actor system、Scheduler、Check pointing 三个重要的组件
4、Task Manager:从 Job Manager 处接收需要部署的 Task。Task Manager 是在 JVM 中的一个或多个线程中执行任务的工作节点。 任务执行的并行性由每个 Task Manager 上可用的任务槽(Slot 个数)决定。 每个任务代表分配给任务槽的一组资源。 例如,如果 Task Manager 有四个插槽,那么它将为每个插槽分配 25% 的内存。 可以在任务槽中运行一个或多个线程。 同一插槽中的线程共享相同的 JVM。
同一 JVM 中的任务共享 TCP 连接和心跳消息。Task Manager 的一个 Slot 代表一个可用线程,该线程具有固定的内存,注意 Slot 只对内存隔离,没有对 CPU 隔离。默认情况下,Flink 允许子任务共享 Slot,即使它们是不同 task 的 subtask,只要它们来自相同的 job。这种共享可以有更好的资源利用率。
7.Flink API
Flink 提供了不同的抽象级别的 API 以开发流式或批处理应用。
7.1 最底层提供了有状态流。
它将通过 Process Function 嵌入到 DataStream API 中。它允许用户可以自由地处理来自一个或多个流数据的事件,并使用一致性、容错的状态。除此之外,用户可以注册事件时间和处理事件回调,从而使程序可以实现复杂的计算。
7.2 DataStream / DataSet API 是 Flink 提供的核心 API
DataSet 处理有界的数据集,DataStream 处理有界或者无界的数据流。
用户可以通过各种方法(map / flatmap / window / keyby / sum / max / min / avg / join 等)将数据进行转换或者计算。
7.3.Table API 是以表为中心的声明式 DSL,其中表可能会动态变化(在表达流数据时)。
Table API 提供了例如 select、project、join、group-by、aggregate 等操作,使用起来却更加简洁(代码量更少)。
你可以在表与 DataStream/DataSet 之间无缝切换,也允许程序将 Table API 与 DataStream 以及 DataSet 混合使用。
7.4 Flink 提供的最高层级的抽象是 SQL 。
这一层抽象在语法与表达能力上与 Table API 类似,但是是以 SQL查询表达式的形式表现程序。SQL 抽象与 Table API 交互密切,同时 SQL 查询可以直接在 Table API 定义的表上执行。
8.Flink 程序与数据流结构
一个完整的 Flink 应用程序结构就是如上两图所示:
1、Source:数据输入,Flink 在流处理和批处理上的 source 大概有 4 类:基于本地集合的 source、基于文件的 source、基于网络套接字的 source、自定义的 source。自定义的 source 常见的有 Apache kafka、Amazon Kinesis Streams、RabbitMQ、Twitter Streaming API、Apache NiFi 等,当然你也可以定义自己的 source。
2、Transformation:数据转换的各种操作,有 Map / FlatMap / Filter / KeyBy / Reduce / Fold / Aggregations / Window / WindowAll / Union / Window join / Split / Select / Project 等,操作很多,可以将数据转换计算成你想要的数据。
3、Sink:数据输出,Flink 将转换计算后的数据发送的地点 ,你可能需要存储下来,Flink 常见的 Sink 大概有如下几类:写入文件、打印出来、写入 socket 、自定义的 sink 。自定义的 sink 常见的有 Apache kafka、RabbitMQ、MySQL、ElasticSearch、Apache Cassandra、Hadoop FileSystem 等,同理你也可以定义自己的 sink。
9.Flink 提供多种 Time 语义
Flink 支持多种 Time,比如
- Event time:事件自身的时间
- Ingestion Time:事件进入flink时的时间
- Processing Time :时间被处理时,机器的系统时间
10. Flink 提供灵活的窗口机制
Flink 支持多种 Window,比如 Time Window、Count Window、Session Window,还支持自定义 Window。
11. Flink 并行的执行任务
Flink 的程序内在是并行和分布式的,数据流可以被分区成 stream partitions,operators 被划分为 operator subtasks; 这些 subtasks 在不同的机器或容器中分不同的线程独立运行;
operator subtasks 的数量在具体的 operator 就是并行计算数,程序不同的 operator 阶段可能有不同的并行数;如下图所示,source operator 的并行数为 2,但最后的 sink operator 为 1:
12. Flink 支持状态存储
Flink 是一款有状态的流处理框架,它提供了丰富的状态访问接口,按照数据的划分方式,可以分为 Keyed State 和 Operator State,在 Keyed State 中又提供了多种数据结构:
- ValueState
- MapState
- ListState
- ReducingState
- AggregatingState
另外状态存储也支持多种方式: - MemoryStateBackend:存储在内存中
- FsStateBackend:存储在文件中
- RocksDBStateBackend:存储在 RocksDB 中
13. Flink 支持容错机制
- Flink 中支持使用 Checkpoint 来提高程序的可靠性,开启了 Checkpoint 之后,Flink 会按照一定的时间间隔对程序的运行状态进行备份,当发生故障时,Flink 会将所有任务的状态恢复至最后一次发生 Checkpoint 中的状态,并从那里开始重新开始执行。
- 另外 Flink 还支持根据 Savepoint 从已停止作业的运行状态进行恢复,这种方式需要通过命令进行触发。
参考链接
《不仅仅是流计算:Apache Flink实践》
《一文让你彻底了解大数据实时计算引擎 Flink》