一、Flink编程数据流模型

1.1、Flink – API封装

Flink 提供不同级别的API封装来支持流/批处理应用程序。

Flink 广播一个对象 flink多个输出_flink


1.2、Flink-编程数据流

  • Source:一个不会结束的数据记录流。
  • Transformations:使用一个或多个数据流作为输入,生成一个或多个数据流结果。
  • Sink:输出数据流。



Flink 广播一个对象 flink多个输出_flink_02



1.3、Flink-并行数据流

  • One-to-One stream
  • Redistributing


Flink 广播一个对象 flink多个输出_flink_03



1.4、Flink-Windows

Flink 广播一个对象 flink多个输出_flink_04

聚合操作(如counts,sums)在streams上的操作和batch processing上面有很大不同。例如,统计流中所有记录的个数是不可能的,因为一般流是不会结束的。所以在流上执行聚合操作,例如count,那么是会被指定为windows范围,例如最近5分钟的count或sum最近的100条记录。

Windows可以时间驱动(每30秒)或数据驱动(每100个记录)


1.5、Flink-Time

  • Event Time
    数据生成的时间。
  • Ingestion time
    数据进入Flink的时间。
  • Processing Time
    使用time-based 操作时的时间。

二、Flink核心概念

2.1、任务和算子链

分布式计算中,Flink 将算子(operator)的 subtask 链接(chain)成 task。

每个 task 由一个线程执行。把算子链接成 tasks 能够减少线程间切换和缓冲的开销,在降低延迟的同时提高了整体吞吐量。

Flink 广播一个对象 flink多个输出_windows_05

2.2、JobManager,TaskManager,Clients

JobManagers (也称为 masters)协调分布式计算。它们负责调度任务、协调 checkpoints、协调故障恢复等。每个 Job 至少会有一个 JobManager。高可用部署下会有多个 JobManagers,其中一个作为 leader,其余处于 standby 状态。

TaskManagers(也称为 workers)执行 dataflow 中的 tasks(准确来说是 subtasks ),并且缓存和交换数据 streams。每个 Job 至少会有一个 TaskManager。

客户端虽然不是运行时(runtime)和作业执行时的一部分,但它是被用作准备和提交 dataflow 到 JobManager 的。提交完成之后,客户端可以断开连接,也可以保持连接来接收进度报告。

Flink 广播一个对象 flink多个输出_数据_06

2.3、Task Slots和资源

每个worker(TaskManager)都是一个JVM进程,并且可以在不同的线程中执行一个或多个 subtasks。为了控制 worker 接收 task 的数量,worker 拥有所谓的task slots(至少一个)。

每个task slots代表TaskManager的一份固定资源子集。例如,具有三个slots的 TaskManager 会将其管理的内存资源分成三等份给每个slot。划分资源意味着subtask之间不会竞争资源,但是也意味着它们只拥有固定的资源。(资源并不包含CPU资源,当前slots之间只是划分任务的内存资源。)

通过调整slot的数量,用户可以决定subtasks的隔离方式。每个TaskManager有一个slot意味着每组task在一个单独的JVM中运行(例如,在一个单独的容器中启动)。拥有多个slots意味着多个subtasks共享同一个JVM。Tasks在同一个 JVM 中共享 TCP 连接(通过多路复用技术)和心跳信息(heartbeat messages)。它们还可能共享数据集和数据结构,从而降低每个 task 的开销。

Flink 广播一个对象 flink多个输出_Flink 广播一个对象_07


默认情况下,Flink允许subtasks共享 slots,即使它们是不同tasks的subtasks,只要它们来自同一个job。因此,一个slot可能会负责这个 job 的整个管道(pipeline)。

允许 slot sharing 有两个好处:

  1. Flink 集群需要与job中使用的最高并行度一样多的 slots。这样不需要计算作业总共包含多少个tasks(具有不同并行度)。
  2. 更好的资源利用率。在没有slot sharing的情况下,简单的 subtasks(source/map())将会占用和复杂的subtasks(window)一样多的资源。通过slot sharing,将示例中的并行度从2增加到6可以充分利用slot的资源,同时确保繁重的 subtask 在 TaskManagers 之间公平地获取资源。
  3. Flink 广播一个对象 flink多个输出_flink_08