点一下关注吧!!!非常感谢!!持续更新!!!
目前已经更新到了:
- Hadoop(已更完)
- HDFS(已更完)
- MapReduce(已更完)
- Hive(已更完)
- Flume(已更完)
- Sqoop(已更完)
- Zookeeper(已更完)
- HBase(已更完)
- Redis (已更完)
- Kafka(已更完)
- Spark(已更完)
- Flink(正在更新!)
章节内容
上节完成了如下的内容:
- Flink 批处理介绍
- Flink 单词统计 Word Count
Flink的重要角色
Flink是非常经典的Master/Slave结构实现,JobManager是Master,TaskManager是Slave。
JobManager(Master)
- 协调分布式执行,他们用来调度Task,协调检查点(CheckPoint),协调失败时恢复等
- Flink运行时至少存在一个Master处理器,如果配置高可用模式则会存在多个Master处理器,它们其中一个是Leader,而其他的都是StandBy。
- JobManager接收的应用包括Jar和JobGraph。
TaskManager(Slave)
也称为 Worker
- 主要职责是从JobManager处接收任务,并部署和启动任务,接收上游的数据处理
- TaskManager是在JVM中的一个或者多个线程中执行任务的工作节点
- TaskManager是在JVM中的一个或多个线程中执行任务的工作节点
- TaskManager在启动的时候会向ResourceManager注册自己的资源信息(Slot数量相等)
角色与功能
- 任务执行:TaskManager 是 Flink 集群中执行分布式数据处理任务的核心组件。它接收 JobManager 分发的任务,执行具体的计算,并将结果返回给 JobManager 或下一个处理节点。
- 资源管理:TaskManager 管理分配给它的计算资源(如 CPU、内存)。Flink 中,每个 TaskManager 都有一个或多个 Slot,每个 Slot 可以执行一个并行子任务(Subtask)。Slot 是 Flink 任务资源调度的基本单元。
- 数据交换与缓存:TaskManager 负责不同任务之间的数据交换,如 Shuffle 操作,并且会对数据进行缓存以提高计算效率。
启动与运行
- 注册到 JobManager:TaskManager 启动时,会向 JobManager 注册自己,报告自身的可用资源信息(如可用内存和 Slot 数量)。JobManager 通过这些信息进行任务的调度和资源分配。
- 执行任务:当 JobManager 将任务分配给 TaskManager 后,TaskManager 会启动相应的 Task,并持续监控它的执行状态。任务完成后,TaskManager 将结果汇报给 JobManager。
- 故障处理:TaskManager 具备一定的故障恢复能力。如果在任务执行过程中发生故障,TaskManager 会向 JobManager 报告,JobManager 根据需要重新分配任务。
通信机制
- 网络通信:TaskManager 通过网络与其他 TaskManager 和 JobManager 进行通信,交换中间结果数据。Flink 提供高效的网络堆栈来支持低延迟和高吞吐量的分布式数据流处理。
- RPC 与心跳机制:TaskManager 和 JobManager 之间通过 RPC(远程过程调用)进行交互,并通过心跳机制确保 TaskManager 的健康状态。如果 JobManager 在一段时间内没有收到 TaskManager 的心跳,则可能认为该 TaskManager 已不可用,并触发故障恢复流程。
监控与日志
- 监控:Flink 提供了多种监控 TaskManager 运行状态的方式,如 Web 界面、日志文件和指标(Metrics)系统。管理员可以通过这些工具监控每个 TaskManager 的资源使用情况、任务执行进度和性能瓶颈。
- 日志:TaskManager 会记录日志文件,详细描述任务执行情况和出现的错误。这些日志对排查问题和调优系统非常重要。
ResourceManager
针对不同的环境和资源提供者,如(YRAN、Kubernetes、独立部署),Flink提供了不同的ResourceManager。它的作用是负责管理Flink的处理资源单元(Slot)
角色与功能
- 资源管理:ResourceManager 负责管理整个集群的计算资源,包括 CPU、内存、和网络资源。它接收来自 JobManager 的资源请求,并调度和分配这些资源,以启动必要数量的 TaskManager 实例。
- 资源请求与分配:当 Flink 应用程序启动时,JobManager 会向 ResourceManager 请求所需的资源,ResourceManager 根据集群的资源状况来分配或启动 TaskManager 实例,以满足这些需求。
- 资源回收:在任务完成后,ResourceManager 负责回收和释放这些资源,使它们可以被其他任务再次利用。
与 JobManager 的协作
- 资源调度:JobManager 会根据作业的并行度和资源需求生成任务计划,并将这些需求发送给 ResourceManager。ResourceManager 负责根据集群的资源情况来决定如何分配这些资源。
- 启动 TaskManager:如果当前集群中可用的 TaskManager 无法满足 JobManager 的需求,ResourceManager 会启动新的 TaskManager 实例来处理任务。这通常通过集成的资源管理平台(如 Yarn、Kubernetes 或 Mesos)来完成。
资源监控
- 资源使用情况监控:ResourceManager 监控整个集群的资源使用情况,包括 CPU、内存、和网络带宽的利用率。这些监控数据可以帮助管理员优化资源分配和调度策略。
- 日志和指标:ResourceManager 生成详细的日志文件,记录资源请求、分配、回收等操作。此外,Flink 还提供了多种监控工具,可以实时查看 ResourceManager 的运行状态和资源使用情况。
Dispatcher
它的作用是提供一个REST接口来让我们提交需要执行的应用。
一旦一个应用提交执行,Dispatcher会启动一个JobManager,并将应用转交给它。
Dispatcher还会启动一个WebUI来提供有关作业作业执行信息
注意:某些应用的提交执行的方式,有可能用不到 Dispatcher
角色与功能
- 作业提交与调度:Dispatcher 负责接收来自客户端的作业提交请求。每当一个作业被提交时,Dispatcher 会启动一个新的 JobManager 实例来管理这个作业的执行。这种设计确保了作业之间的隔离,防止一个作业的失败影响到其他作业。
- 多作业管理:Dispatcher 可以同时管理多个作业。每个作业都有独立的 JobManager 实例,Dispatcher 负责监控这些作业的状态,并在作业完成或失败后回收资源。
- REST 接口:Dispatcher 提供一个 RESTful 接口,允许用户通过 HTTP 请求提交、查询和管理作业。这使得 Flink 可以与其他系统更容易地集成,并简化了自动化作业调度的实现。
与 JobManager 的关系
- 独立 JobManager:在 Dispatcher 负责的架构下,每个提交的作业都会启动一个独立的 JobManager 实例。这样做的好处是每个作业都是隔离运行的,这提升了集群的稳定性和健壮性。
- 任务调度:Dispatcher 在收到作业提交请求后,首先决定如何分配资源并启动相应的 JobManager,然后由这个 JobManager 来管理和调度 TaskManager 上的具体任务执行。
架构与组件交互
- 资源管理交互:Dispatcher 并不直接管理集群的资源,而是依赖于 ResourceManager 来提供和调度所需的资源。在作业提交时,Dispatcher 向 ResourceManager 请求启动 JobManager 和 TaskManager 实例。
- 与客户端交互:Dispatcher 是客户端提交作业的入口点。客户端通过 REST API 与 Dispatcher 通信,提交作业、取消作业或查询作业状态。Dispatcher 负责将这些请求分发到对应的 JobManager。
各个组件之间关系
Flink运行架构
Flink程序结构
Flink程序的基本构建块是流和转换(请注意,Flink和DataSet API中使用的Dataset也是内部流)。从概念上讲,流是(可能永远无止境的)数据记录流,而转换是将一个或者多个流输入,并产生一个或多个输出流。
上图表述了Flink的应用程序结构,有Source(源头)、Transformation(转换)、Sink(接收器)三个重要的组成部分。
Source
数据源,定义Flink从哪里加载数据,Flink在流处理和批处理上的Source大概有4类:
- 基于本地集合的Source
- 基于文件的Source
- 基于网络套接字的Source
- 自定义的Source(Apache Kafka、RabbitMQ等)
Transformation
数据转换的各种操作,也称为算子,有Map、FlatMap、Filter、KeyBy、Reduce、Window等,可以将数据转换计算成你想要的数据。
Sink
接收器,Flink将转换计算后的数据发送的地点,定义了结果数据的输出方向,Flink常见的Sink大概有这么几类:
- 写入文件
- 打印出来
- 写入Socket
- 自定义Sink(Apache Kafka、RabbitMQ、MySQL、Elasticsearch、HDFS等)
Task和SubTask
- Task是一个阶段多个功能相同的SubTask集合,类似于Spark中的TaskSet
- SubTask(子任务)是Flink中任务最小的执行单元,是一个Java类的实例,这个Java类中有属性和方法,完成具体的计算逻辑。比如执行一个操作map,分布式场景下会有多个线程中同时执行,每个线程中执行的都叫一个SubTask。
OperatorChain
Flink的所有操作都叫做Operator,客户端在提交任务的时候会对Operator进行优化操作,能进行合并的Operator会被合并为一个Operator,合并后的Operator成为OperatorChain,实际上就是一个执行链,每个执行链会在TaskManager上一个独立的线程中执行。
Flink中的数据传输
在运行过程中,应用中的任务会持续进行数据交换。
为了有效利用网络资源和提高吞吐量,Flink在处理任务的数据传输过程中,采用了缓冲机制。
任务槽和槽共享
任务槽也叫做 Task-Slot,槽共享也叫 Slot-Sharing
每个TaskManager是一个JVM的进程,可以在不同的线程中执行一个或多个子任务。
为了控制一个Worker能接收多少个Task,Worker通过TaskSlot来进行控制(一个Worker至少有一个TaskSlot)
任务槽
每个TaskSlot表示TaskManager拥有资源的一个固定大小的子级,一般来说:我们分配的槽的个数都是CPU的核数相等,比如6核,那就分配6个槽。
Flink将进程的内存进行了划分到多个Slot中,假设一个TaskManager机器有3个Slot,那么每个Slot占1/3的内存(平均分配)。
内存被划分到不同的Slot之后可以得到的好处如下:
- TaskManager最多能同时并发执行的任务是可以控制的,那就是3个,因为不能超过Slot的数量。
- Slot有独占的内存空间,这样在一个TaskManager中可以运行多个不同的作业,作业之间不受影响。
槽共享
默认情况下,Flink允许子任务subtask(map[1] map[2] keyby[1] keyby[2])共享插槽,即使他们是不同的任务的子任务,只要他们来自同一个作业。
结果是一个槽可以保存作业的整个管道。