1.7.Flink scala shell代码调试
1.7.1.Flink scala shell代码调试语法
1.8.Flink基本原理及应用场景
1.8.1.Flink特点
1.8.2.Flink架构图
1.8.2.1.Flink集群的解剖
1.8.2.1.1.JobManager
1.8.2.1.2.TaskManagers
1.8.2.1.3.Tasks and Operator Chains
1.8.2.1.4.Task Slots 和 Resources
1.8.2.1.5.Flink Application Execution
1.8.2.1.6.Flink Session集群
1.8.2.1.7.Flink Job 集群
1.8.2.1.8.Flink Application集群
1.8.3.Flink基本组件介绍
1.8.4.Flink的流处理与批处理
1.8.5.三种数据传输模型
1.8.6.数据处理的模型
1.8.7.Flink应用场景分析

1.7.Flink scala shell代码调试

针对初学者,开发的时候容易出错,如果每次都打包进行调试,比较麻烦,并且也不好定位问题,可以在scala shell命令行下进行调试

scala shell方式支持流处理和批处理。当启动shell命令行之后,两个不同的ExecutionEnvironments会被自动创建。使用senv(Stream)和benv(Batch)分别去处理流处理和批处理程序。(类似于spark-shell中sc变量)

bin/start-scala-shell.sh [local|remote|yarn] [options]

scala> val text = benv.fromElements("hello you","hello world")  
scala> val counts = text.flatMap { _.toLowerCase.split("\\W+") }.map { (_, 1) }.groupBy(0).sum(1)  
scala> counts.print()

1.7.1.Flink scala shell代码调试语法

flink stadnlone 集群稳定性 flink集群架构_应用程序

1.8.Flink基本原理及应用场景

Apache Flink是一个开源的分布式,高性能,高可用,准确的流处理框架。
主要由Java代码实现。
支持实时流(stream)处理和批(batch)处理,批数据只是流数据的一个极限特例。
Flink原生支持了迭代计算、内存管理和程序优化。

1.8.1.Flink特点

Flink的数据来源可以是:应用(Applications)、传感器和设备(Sensors & Devices)、文件系统和存储(File Systems & Storage)、日志消息(Message Logs)

Flink的特点:流式优先(Streaming-first)、连续处理(continuous processing)、容错(Fault-tolerant)、有状态的计算(stateful computations)、可伸缩(Scalable)、可支持上千个节点(to 1000s of nodes and beyond)、性能(Performance)、高吞吐 低延迟(high throughput,low latency)。

Flink的数据下层位置: 应用(Applications)、数据库(Databases)、文件系统和存储(File Systems & Storage)、日志消息(Message Logs)。

flink stadnlone 集群稳定性 flink集群架构_流处理_02

1.8.2.Flink架构图

flink stadnlone 集群稳定性 flink集群架构_应用程序_03


Flink是一个分布式系统,需要对计算资源进行有效的分配和管理,才能执行流应用程序。它集成了所有常见的集群资源管理器,如Hadoop YARN、Apache Mesos和Kubernetes,但也可以设置为作为独立集群运行,甚至作为库运行。

1.8.2.1.Flink集群的解剖

Flink运行时由两种类型的进程组成:JobManager和一个或多个TaskManagers。

要了解一个系统,一般都是从架构开始。我们关心的问题是:系统部署成功后各个节点都启动了哪些服务,各个服务之间又是怎么交互和协调的。下方是Flink集群启动后架构图。

flink stadnlone 集群稳定性 flink集群架构_flink_04

图 1 集群部署解析图

客户端(Client)不是运行时和程序执行的一部分,但用于准备和发送dataflow到JobManager。之后,客户端(Client)可以断开连接(detached mode),或者保持连接以接收进度报告(attached mode)。客户端要么作为触发执行的Java/Scala程序的一部分运行,要么在命令行进程中运行。

JobManager和taskmanager可以以各种方式启动:作为独立集群( standalone cluster)直接在机器上启动,在容器中,或者由YARN或Mesos等资源框架管理。TaskManagers连接到JobManagers,宣布它们是可用的,并分配工作。

1.8.2.1.1.JobManager

JobManager有许多与协调Flink应用程序的分布式执行相关的职责:它决定何时调度下一个任务(或一组任务),对已完成的任务或执行失败作出反应,协调检查点,协调失败的恢复,等等。这个过程包括三个不同的组成部分:
ResourceManager
ResourceManager负责Flink集群中的资源去/分配和供应——它管理任务槽(task slots),这些任务槽是Flink集群中的资源调度单元(请参阅TaskManagers)。Flink为不同的环境和资源提供者(如YARN、Mesos、Kubernetes和独立部署(standalone deployments))实现了多个resourcemanager。在独立部署中,ResourceManager只能分发可用的任务管理器的槽(slots),不能自己启动新的任务管理器。

Dispatcher
Dispatcher提供一个REST接口来提交要执行的Flink应用程序,并为每个提交的作业启动一个新的JobMaster。它还运行Flink WebUI来提供关于作业执行的信息。

JobMaster
JobMaster 负责管理单个JobGraph的执行。多个作业可以在一个Flink集群中同时运行,每个作业都有自己的作业管理器。

至始至终至少有一个JobManager。一个HA集群中可能有多个JobManager。在HA中,其中一个总是leader,另外的就是standby。

1.8.2.1.2.TaskManagers

TaskManagers (也称为workers)执行(dataflow)的任务,缓冲和交换data streams。

必须始终至少有一个TaskManager。TaskManager中资源调度的最小单元是一个task slot。任务管理器中的task slot的数量表示并发处理任务的数量。注意,多个operators可以在一个task slot中执行(请参阅任务和操作符链(Tasks and Operator Chains))。

1.8.2.1.3.Tasks and Operator Chains

对于分布式执行,Flink将操作子任务(subtasks)连接到一起,形成多个任务。每个任务由一个线程执行。将operators链接到任务中是一种有用的优化:它减少了线程到线程的切换和缓冲开销,提高了总体吞吐量,同时减少了延迟。这个链的行为可以配置。

下图中的样例dataflow由5个子任务执行,因此有5个并行线程(带有3个Task的和2个thread的)。

flink stadnlone 集群稳定性 flink集群架构_应用程序_05

1.8.2.1.4.Task Slots 和 Resources

每个worker (TaskManager)都是一个JVM进程,并且可以在单独的线程中执行一个或多个子任务。为了控制TaskManager接受多少任务,它有所谓的任务槽(至少一个)。

每个task slot表示TaskManager的一个固定资源子集。例如,一个有三个slot的TaskManager,会将其托管内存的1/3分配给每个插slot。对资源进行分段意味着子任务不会与其他作业的子任务争夺托管内存,而是拥有一定数量的保留托管内存。注意,这里没有发生CPU隔离;当前slots 只分隔任务的托管内存。

通过调整task slots的数量,用户可以定义子任务如何相互隔离。每个TaskManager有一个槽意味着每个任务组在单独的JVM中运行(例如,JVM可以在单独的容器中启动)。拥有多个slots意味着更多子任务共享同一个JVM。相同JVM中的任务共享TCP连接(via multiplexing)和心跳消息。它们还可以共享数据集和数据结构,从而减少每个任务的开销。

flink stadnlone 集群稳定性 flink集群架构_flink_06


默认情况下,Flink允许子任务共享slots,即使它们是不同任务的子任务,只要它们来自相同的作业。结果是,一个slot可以容纳作业的整个管道(pipeline)。允许这种slot共享有两个主要好处:

Flink集群需要的任务slot与作业中使用的最高并行度相同。不需要计算一个程序总共包含多少任务(具有不同的并行性)。

更容易获得更好的资源利用。如果没有slot共享,非密集的source/map()子任务将阻塞和资源密集的窗口子任务一样多的资源。使用slot共享,将示例中的基本并行性从2个增加到6个,可以充分利用有slot的资源,同时确保繁重的子任务在任务管理器中得到公平分配。

flink stadnlone 集群稳定性 flink集群架构_应用程序_07

1.8.2.1.5.Flink Application Execution

Flink应用程序是任何从main()方法生成一个或多个Flink作业的用户程序。这些作业可以在本地JVM (LocalEnvironment)中执行,也可以在带有多台机器的远程集群设置(RemoteEnvironment)上执行。对于每个程序,ExecutionEnvironment提供了控制作业执行(例如设置并行性)和与外部世界交互的方法(参见Flink程序的剖析)。

Flink应用程序的作业可以提交给长时间运行的Flink session集群、专用的Flink作业集群或Flink应用程序集群。这些选项之间的区别主要与集群的生命周期和资源隔离保证有关。

1.8.2.1.6.Flink Session集群

部署在yarn集群上的flink集群都是把资源的管理交给了yarn来管理。yarn session的部署模式就是先预先在yarn集群上启动一个flink集群,我们可以把我们写好的flink任务直接提到这个集群上。
启动集群的命令如下:

${FLINK_HOME}/bin/yarn-session.sh

1:如果没指定-d,这种情况集群会和客户端一直保持着连接,客户端退出之后,集群也会退出。

2:提交任务
往yarn session集群提交任务,只需要在相应的客户端机器上,通过${FLINK_HOME}/bin/flink run -d user.jar 这样的命令就可以提交到session集群.

此外我们还可以通过web ui最后一项来提交任务

flink stadnlone 集群稳定性 flink集群架构_流处理_08

3:这种session模式一般适用于批任务,也就是执行一段时间以后可以终止的任务,因为对于这种短时间执行的任务,可以避免在申请资源方面浪费过多时间。

4:集群启动之后,是没有给flink集群分配资源的,当提交任务之后,yarn集群会根据请求再给任务分配资源,任务执行完成之后,系统隔一段时间会释放相应的资源.(这个时间是可配置的,为了防止马上有任务又来了,重新申请资源)


集群生命周期:在Flink Session 集群中,客户端连接到一个预先存在的长时间运行的集群,该集群可以接受多个作业提交。即使完成了所有作业,集群(和JobManager)仍将继续运行,直到手动停止会话。因此,Flink session集群的生存期不绑定到任何Flink作业的生存期。
资源隔离:任务管理器slots 由ResourceManager在作业提交时分配,并在作业完成后释放。由于所有作业都共享同一个集群,因此集群资源(如提交作业阶段的网络带宽)存在竞争。这个共享设置的一个限制是,如果一个任务管理器崩溃,那么在这个任务管理器上运行的所有任务都将失败;同样,如果JobManager上发生致命错误,它将影响集群中运行的所有作业。
其他注意事项:拥有一个预先存在的集群可以节省大量应用资源和启动taskmanager的时间。在作业的执行时间非常短且高启动时间会对端到端用户体验产生负面影响的场景中,这一点非常重要——就像对短查询进行交互式分析的情况一样,在这种情况下,作业可以使用现有资源快速执行计算。

1.8.2.1.7.Flink Job 集群

1:上面讲了session模式部署集群,这种模式可以在一个集群里跑很多的任务,这些任务共享了flink集群的资源,隔离性做的不是很好,所以flink还提供了另外一种执行模式:yarn per job模式。
2:这种模式会在yarn上为每个flink任务都建立一个单独的集群,优势就是每个任务单独的进行资源管理,和其他任务资源隔离。这种模式适用于对启动时间不太敏感,需要长时间运行的流任务。
3:启动命令

${FLINK_HOME}/bin/flink run -d -p 4 -ys 2 -m yarn-cluster -c com.example.Test userjar.jar arg1 arg2

-d 采用分离模式

-p 程序的并行度

-ys 每个taskmanager有几个slot,我们可以简单的理解为flink会把taskmanager的内存分成几份,在某些条件下,程序可以共用slot,提高效率,至于slot的概念,我们后续再讲,今天就不多说了。用并行度除以这个值,然后就会得到flink会启动几个taskmanager

,所以为了避免有多余的slot,我们最好设置并行度除以这个ys值能整除。

-c 程序的入口类,我们可以在程序打包的时候指定入口类,如果没有指定或者程序中有很多类,我们就需要通过这个-c参数来指定入口类了。

在命令行最后的参数是用户jar包的参数.

停止命令

第一,我们可以在flink的页面上通过停止flink的任务来停止集群,在我们停止了flink任务之后,yarn会自动释放相应的资源。

flink stadnlone 集群稳定性 flink集群架构_flink_09

第二,通过命令行来停止:

${FLINK_HOME}/bin/flink stop -m yarn-cluster -yid application_1592386606716_0005 c8ee546129e8480809ee62a4ce7dd91d

这个时候需要指定yarn applicationId和flink job id
第三,通过程序来停止

如果做了一个实时平台这样的系统,就不能手工通过命令行来停止了,可以调用相应的api来停止任务.

启动流程
当执行完相应的命令之后,系统会把flink的jar、相关的配置文件、用户的jar都上传到hdfs
的一个临时目录,默认是/user/{USER}/.flink/{applicationId},
然后再构建flink集群的时候,再去找个目录去获取,程序部署成功之后,删除相应的临时目录


集群生命周期:在Flink作业集群中,可用的集群管理器(如YARN或Kubernetes)用于为每个提交的作业启动一个集群,该集群仅对该作业可用。在这里,客户端首先请求资源从集群管理器启动JobManager并提交作业调度程序运行在这个过程。TaskManagers然后lazily 地分配资源需求的基础上工作。一旦任务完成,Flink任务集群将被拆除。
资源隔离:JobManager中的致命错误只会影响在该Flink作业集群中运行的一个作业。
其他注意事项:因为ResourceManager申请,等待外部资源管理组件启动TaskManager流程和分配资源,集群Flink工作更适合大型长期的工作,有高要求,不敏感,再启动时间。

1.8.2.1.8.Flink Application集群

这种模式是在flink 1.11 版本中提供的,flink的yarn per job模式启动的时候会把本地的flink的jar和用户的jar都上传到hdfs,这个过程非常的消耗网络的带宽,如果同时有多个人提交任务的话,那么对网络的影响就更大,此外,每次提交任务的时候flink的jar包是一样的,也不用每次都拷来拷去的,所以flink提供了一种新的application模式,可以把flink的jar和用户的jar都预先放到hdfs上,这样就能省去yarn per job模式提交任务的jar包拷贝工作,节省了带宽,加快了提交任务的速度。

具体的命令如下:

./bin/flink run-application -p 1 -d -t yarn-application -yD yarn.provided.lib.dirs="hdfs://localhost/data/flink/libs/" hdfs://localhost/data/flink/user-lib/TopSpeedWindowing.jar

-yD yarn.provided.lib.dirs :用来指定存放flink jar的目录
最后一个参数是用户的jar在hdfs上的路径.


集群生命周期:Flink应用程序集群是一个专用的Flink集群,它只执行来自一个Flink应用程序的作业,并且main()方法在集群上运行,而不是在客户机上运行。作业提交是一个一步完成的过程:您不需要首先启动Flink集群,然后将作业提交到现有的集群会话;相反,您可以将应用程序逻辑和依赖关系打包到一个可执行作业JAR中,而集群入口点(ApplicationClusterEntryPoint)负责调用main()方法来提取JobGraph。例如,这允许您像部署Kubernetes上的任何其他应用程序一样部署Flink应用程序。因此,Flink应用程序集群的生存期绑定到Flink应用程序的生存期。
资源隔离:在Flink应用程序集群中,ResourceManager和Dispatcher作用域被限定为单个Flink应用程序,这提供了比Flink会话集群更好的关注点隔离。

1.8.3.Flink基本组件介绍

Data Source
Transformations
Data Sink

1.8.4.Flink的流处理与批处理

在大数据处理领域,批处理任务与流处理任务一般被认为是两种不同的任务,一个大数据框架一般会被设计为只能处理其中一种任务。
例如:Storm只支持流处理任务,而MapReduce、Spark支持批处理任务。Spark Streaming是Apache Spark之上支持流处理任务的子系统,看似是一个特例,其实并不是——Spark Streaming采用了一种micro-batch的架构,即把输入的数据流切分成细粒度的batch,并为每一种batch数据提交一个批处理的Spark任务,所以Spark Streaming本质上还是基于Spark批处理系统对流式数据进行处理,和Storm完全流式的数据处理方式完全不同。

Flink通过灵活的执行引擎,能够同时支持批处理任务与流处理任务
A:在执行引擎这一层,流处理系统与批处理系统最大不同在于节点间的数据传输方式。
B:对于一个流处理系统,其节点间数据传输的标准模型是:当一条数据被处理完成后,序列化到缓存中,然后立刻通过网络传输到下一个节点,由下一个节点继续处理。
C:而对于一个批处理系统,其节点间数据传输的标准模型是:当一条数据被处理完成后,序列化到缓存中,并不会立刻通过网络传输到下一个节点,当缓存写满,就持久化到本地硬盘上,当所有数据都被处理完成后,才开始将处理后的数据通过网络传输到下一个节点。
D:这两种数据传输模式是两个极端,对应的是流处理系统对低延迟的要求和批处理系统对高吞吐量的要求。
E:Flink的执行引擎采用了一种十分灵活的方式,同时支持了这两种数据传输模型。
F:Flink以固定的缓存块为单位进行网络数据传输,用户可以通过设置缓存块超时值指定缓存块的传输时机。如果缓存块的超时值为0,则Flink的数据传输方式类似上文所提到流处理系统的标准模型,此时系统可以获得最低的处理延迟。
G:如果缓存块的超时值为无限大,则Flink的数据传输方式类似上文所提到批处理系统的标准模型,此时系统可以获得最高的吞吐量。
H:同时缓存块的超时值也可以设置为0到无限大之间的任意值。缓存块的超时阈值越小,则Flink流处理执行引擎的数据处理延迟越低,但吞吐量也会降低,反之亦然。通过调整缓存块的超时阈值,用户可根据需求灵活地权衡系统延迟和吞吐量。

1.8.5.三种数据传输模型

flink stadnlone 集群稳定性 flink集群架构_flink_10

1.8.6.数据处理的模型

流处理模型

flink stadnlone 集群稳定性 flink集群架构_流处理_11


批处理模型

flink stadnlone 集群稳定性 flink集群架构_应用程序_12

Flink处理模型

flink stadnlone 集群稳定性 flink集群架构_flink_13

1.8.7.Flink应用场景分析

优化电商网站的实时搜索结果
阿里巴巴的所有基础设施团队使用flink实时更新产品细节和库存信息(Blink)
针对数据分析团队提供实时流处理服务
通过flink数据分析平台提供实时数据分析服务,及时发现问题。
网络/传感器检测和错误检查
Bouygues电信公司,是发过最大的电信供应商之一,使用fink监控其优先和无线网络,实现快速故障响应。
商业智能分析ETL
Zalando使用flink转换数据以便于加载到数据仓库,将复杂的转换操作转化为相对简单的并确保分析终端用户可以更快的访问数据(实时ETL)