问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

Flink 原理详解

创作时间:
作者:
@小白创作中心

Flink 原理详解

引用
1
来源
1.
https://cloud.tencent.com/developer/article/1673761

Apache Flink是一个开源的流处理框架,支持流处理和批处理,具有低延迟、高吞吐、容错和可扩展等特点。本文将详细介绍Flink的基本原理、架构设计、编程模型以及与Spark Streaming的对比分析。

Flink基本概念

Flink是一个流处理框架,支持流处理和批处理。其特点是流处理有限、可容错、可扩展、高吞吐和低延迟。

  • 流处理:处理一条数据后,立即在下一个节点从缓存中取出数据进行计算。
  • 批处理:只有在处理完一批数据后,才会通过网络传输到下一个节点。

流处理的优点是低延迟,批处理的优点是高吞吐。Flink同时支持这两种处理模式,其网络传输设计固定缓存块为单位,用户可以设置缓存块的超时值来决定缓存块什么时候进行传输。当数据大于0时进行处理就是流式处理,如果设置为无限大就是批处理模型。

Flink基本架构

Flink集群主要包括JobManager和TaskManager两个组件:

  • JobManager:负责调度Job并协调Task做checkpoint,类似于Storm的Nimbus。从Client处接收到Job和JAR包等资源后,会生成优化后的执行计划,并以Task的单元调度到各个TaskManager去执行。

  • TaskManager:在启动时设置好了槽位数(Slot),每个slot能启动一个Task,Task为线程。从JobManager处接收需要部署的Task,部署启动后,与自己的上游建立Netty连接,接收数据并处理。

Flink On Yarn结构

Flink on Yarn是由Client提交App到ResourceManager(RM)上,然后RM分配一个AppMaster负责运行Flink JobManager和Yarn AppMaster。AppMaster分配容器去运行Flink TaskManager。

Spark Streaming架构

Spark Streaming将流处理分成微批处理的作业,最后的处理引擎是Spark Job。Spark Streaming把实时输入数据流以时间片Δt(如1秒)为单位切分成块,Spark Streaming会把每块数据作为一个RDD,并使用RDD操作处理每一小块数据。每个块都会生成一个Spark Job处理,然后分批次提交job到集群中去运行,运行每个 job的过程和真正的spark 任务没有任何区别。

JobScheduler负责Job的调度,通过定时器每隔一段时间根据Dstream的依赖关系生一个一个DAG图。ReceiverTracker负责数据的接收、管理和分配。ReceiverSupervisor在启动Receiver的时候会启动Receiver,Receiver不断的接收数据,通过BlockGenerator将数据转换成Block。定时器会不断的把Block数据通过BlockManager或者WAL进行存储,数据存储之后ReceiverSupervisorlmpl会把存储后的数据的元数据Metadate汇报给ReceiverTracker。

Spark on Yarn

Spark on Yarn的Cluster模式中,Spark client向ResourceManager提交job请求,ResourceManager会分配一个AppMaster,Driver和AppMaster运行在AppMaster节点里。AppMaster把Receiver作为一个Task提交给Spark Executor节点,Receiver启动接受数据,生成数据块,并通知Spark Appmaster。AppMaster会根据数据块生成相应的Job,并把Job提交给空闲的Executor去执行。

对比Flink和Spark Streaming的Cluster模式可以发现,都是AM里面的组件(Flink是JM,spark streaming是Driver)承载了task的分配和调度,其他container承载了任务的执行(Flink是TM,spark streaming是Executor)。不同的是Spark Streaming每个批次都要与driver进行通信来进行重新调度,这样延迟性远低于Flink。

实时框架选择指南

在选择实时处理框架时,需要考虑以下因素:

  1. 流数据是否需要进行状态管理
  2. At-least-once或者Exectly-once消息投递模式是否有特殊要求
  3. 对于小型独立的项目,并且需要低延迟的场景,建议使用Storm
  4. 如果你的项目已经使用了Spark,并且秒级别的实时处理可以满足需求的话,建议使用Spark Streaming
  5. 要求消息投递语义为Exactly Once的场景;数据量较大,要求高吞吐低延迟的场景;需要进行状态管理或窗口统计的场景,建议使用Flink

Flink编程结构

Flink提供的API主要有DataStream和DataSet,他们都是不可变的数据集合,不可以增加删除中的元素。通过Source创建DataStream和DataSet。

  1. 获取运行时
// 流处理
StreamingExecutionEnvironment
// 批处理
ExecutionEnvironment

在创建运行时有:

createLocalEnvironment 和 createRemoteEnvironment
  1. 添加外部数据源
env.addSource(...)
  1. 定义算子
input.map{}
  1. 定义Sink
stats.addSink(...)
  1. 启动程序
env.execute()

Flink优化与调度策略

Flink的每一个Operator称为一个任务,Operator的每一个实例称为子任务,每一个任务在JVM线程中执行。可以将多个子任务链接成一个任务,减少上下文切换的开销,降低延迟。

source和算子map如果是one by one的关系,他们的数据交换可以通过缓存而不是网络通信。

TaskManager为控制执行任务的数量,将计算资源划分多个slot,每个slot独享计算资源,这种静态分配利于任务资源隔离。同一个任务可以共享一个slot,不同作业不可以。

Flink使用slot来隔离多个作业任务。

  1. 调度策略
env.addSource(...).setParallelism(4)
   .map(...).setParallelism(4)
   .reduce(...).setParallelism(3)

这里因为Source和Map并行度都是4采用直连方式,他们的数据通信采用缓存形式。所以一共需要两个TaskManager,source,Map一个,reduce一个,每个TaskManager要3个slot。

  1. 作业控制

JobManager将JobGraph部署ExecutionGraph:

  1. JobGraph由Operator和传输通道的数据缓存组成。Operator是计算图中的顶点JobVertex。
  2. ExecutionGraph由ExecutionVertex和中间结果的多个分区组成。


设置的并行度,可以让一个ExecJobVertex对应多个并行的ExecVertex实例。Flink通过状态机管理ExecGraph的作业执行进度。

Flink如何管理内存

Flink将对象序列化为固定数量的预先分配的内存段,而不是直接把对象放在堆内存上。Flink TaskManager是由几个内部组件组成的:actor系统(负责与Flink master协调)、IOManager(负责将数据溢出到磁盘并将其读取回来)、MemoryManager(负责协调内存使用)。

流处理API

数据源

env.readTextFile("/path")
env.readFile(inputFormat,"path")
env.socketTextStream("localhost", port,'\n')
env.fromElements(data: T*)
env.addSource(new FlinkKafkaConsumer08)

Sink

windowCounts.writeAsCsv()
windowCounts.print().setParallelism(1)
windowCounts.addSink()
windowCounts.writeToSocket()

时间

处理时间:取自Operator的机器系统时间
事件时间:由数据源产生
进入时间:被Source节点观察时的系统时间

env.setStreamTimeCharacteristic(TimeCharacteristic.EventTime)
env.setStreamTimeCharacteristic(TimeCharacteristic.IngestionTime)
env.setStreamTimeCharacteristic(TimeCharacteristic.ProcessingTime)

水印

如果数据源没有自己正确创建水印,程序必须自己生成水印来确保基于事件的时间窗口可以正常工作。DataStream提供了周期性水印、间歇式水印和递增式水印。

总结

本文详细介绍了Flink的基本原理、架构设计、编程模型以及与Spark Streaming的对比分析。对于想要深入了解Flink的读者来说,这篇文章具有较高的参考价值。但是需要注意的是,文章发布于2020年,距今已有5年时间,技术领域更新迭代较快,Flink的版本和特性可能已经发生了变化。因此,文章中的某些内容可能已经过时,需要谨慎对待。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号