在分布式运行环境中,Flink 提出了算子链的概念,Flink 将多个算子放在一个任务中,由同一个线程执行,减少线程之间的切换、消息的序列化/反序列化、数据在缓冲区的交换,减少延迟的同时提高整体的吞吐量。
在 Flink 集群中,一个 TaskManger 就是一个 JVM 进程,并且会用独立的线程来执行 task,为了控制一个 TaskManger 能接受多少个 task,Flink 提出了 Task Slot 的概念。
我们可以简单的把 Task Slot 理解为 TaskManager 的计算资源子集。假如一个 TaskManager 拥有 5 个 slot,那么该 TaskManager 的计算资源会被平均分为 5 份,不同的 task 在不同的 slot 中执行,避免资源竞争。但是需要注意的是,slot 仅仅用来做内存的隔离,对 CPU 不起作用。那么运行在同一个 JVM 的 task 可以共享 TCP 连接,减少网络传输,在一定程度上提高了程序的运行效率,降低了资源消耗。
Flink 在编程模型上提供了 DataStream 和 DataSet 两套 API,并没有做到事实上的批流统一,因为用户和开发者还是开发了两套代码。正是因为 Flink Table & SQL 的加入,可以说 Flink 在某种程度上做到了事实上的批流一体。
动态表的查询与静态表一样,但是,在查询动态表的时候,SQL 会做连续查询,不会终止。
WINDOW
根据窗口数据划分的不同,目前 Apache Flink 有如下 3 种:
滚动窗口,窗口数据有固定的大小,窗口中的数据不会叠加;
滑动窗口,窗口数据有固定大小,并且有生成间隔;
会话窗口,窗口数据没有固定的大小,根据用户传入的参数进行划分,窗口数据无叠加;
一个完整的 Flink Table & SQL Job 也是由 Source、Transformation、Sink 构成:
Source 部分来源于外部数据源,我们经常用的有 Kafka、MySQL 等;
Transformation 部分则是 Flink Table & SQL 支持的常用 SQL 算子,比如简单的 Select、Groupby 等,当然在这里也有更为复杂的多流 Join、流与维表的 Join 等;
Sink 部分是指的结果存储比如 MySQL、HBase 或 Kakfa 等。
➜ [flink-1.10.0]# ./bin/start-cluster.sh
Standalone 模式是集群模式的一种,但是这种模式一般并不运行在生产环境中,原因和 on yarn 模式相比:
在 Flink on yarn 模式下,启动集群的方式有两种:
直接在 yarn 上运行任务
yarn session 模式
在 Flink 这个框架中,有很多独有的概念,比如分布式缓存、重启策略、并行度等,这些概念是我们在进行任务开发和调优时必须了解的,这一课时我将会从原理和应用场景分别介绍这些概念。
Flink 提供的分布式缓存类型 Hadoop,目的是为了在分布式环境中让每一个 TaskManager 节点保存一份相同的数据或者文件,当前计算节点的 task 就像读取本地文件一样拉取这些配置。
我们在上一课时中介绍过 Flink 的配置文件,其中有一个参数 jobmanager.execution.failover-strategy: region。
Flink 支持了不同级别的故障恢复策略,jobmanager.execution.failover-strategy 的可配置项有两种:full 和 region。
Flink 在判断需要重启的 Region 时,采用了以下的判断逻辑:
发生错误的 Task 所在的 Region 需要重启;
如果当前 Region 的依赖数据出现损坏或者部分丢失,那么生产数据的 Region 也需要重启;
为了保证数据一致性,当前 Region 的下游 Region 也需要重启。
Flink 提供了多种类型和级别的重启策略,常用的重启策略包括:
固定延迟重启策略模式
失败率重启策略模式
无重启策略模式
Flink 在判断使用的哪种重启策略时做了默认约定,如果用户配置了 checkpoint,但没有设置重启策略,那么会按照固定延迟重启策略模式进行重启;如果用户没有配置 checkpoint,那么默认不会重启。
并行度是 Flink 执行任务的核心概念之一,它被定义为在分布式运行环境中我们的一个算子任务被切分成了多少个子任务并行执行。我们提高任务的并行度(Parallelism)在很大程度上可以大大提高任务运行速度。
在代码中可以调用 setParallelism 方法来设置每一个算子的并行度
我们在创建 Flink 的上下文时可以显示的调用 env.setParallelism() 方法,来设置当前执行环境的并行度,这个配置会对当前任务的所有算子、Source、Sink 生效。当然你还可以在算子级别设置并行度来覆盖这个设置。
用户在提交任务时,可以显示的指定 -p 参数来设置任务的并行度,例如:
./bin/flink run -p 10 WordCount.jar
我们在上一课时中提到了 flink-conf.yaml 中的一个配置:parallelism.default,该配置即是在系统层面设置所有执行环境的并行度配置。
整体上讲,这四种级别的配置生效优先级如下:算子级别 > 执行环境级别 > 提交任务级别 > 系统配置级别。
在这里,要特别提一下 Flink 中的 Slot 概念。我们知道,Flink 中的 TaskManager 是执行任务的节点,那么在每一个 TaskManager 里,还会有“槽位”,也就是 Slot。Slot 个数代表的是每一个 TaskManager 的并发执行能力。
假如我们指定 taskmanager.numberOfTaskSlots:3,即每个 taskManager 有 3 个 Slot ,那么整个集群就有 3 * taskManager 的个数多的槽位。这些槽位就是我们整个集群所拥有的所有执行任务的资源。
目前 Flink 支持如下 3 种:
滚动窗口,窗口数据有固定的大小,窗口中的数据不会叠加;
滑动窗口,窗口数据有固定的大小,并且有生成间隔;
会话窗口,窗口数据没有固定的大小,根据用户传入的参数进行划分,窗口数据无叠加。
Flink 中的时间分为三种:
事件时间(Event Time),即事件实际发生的时间;
摄入时间(Ingestion Time),事件进入流处理框架的时间;
处理时间(Processing Time),事件被处理的时间。
下面的图详细说明了这三种时间的区别和联系:
-ys 2 Number of slots per TaskManager
-p 4 The parallelism with which to run the progra
-yjm 1024 Memory for JobManager
-ytm 1024 Memory per TaskManager Container