Flink分布式运行环境

原创
2017/05/23 16:43
阅读数 222

任务和操作算子链接(operator chain)

    分布式执行过程中,Flink会将操作算子子任务(subtask)链接成一个个具体的任务(task),在不同的线程中执行。链接操作算子在一起实际上是个优化:减少了线程间传递与缓存的开销,从而提升了TPS还减少了延时。下图即表示了5个子任务链接的情况:

Job Manager, Task Manager, 客户端

Flink运行时由两类进程组成:

  • JobManager——也被称为master。负责协调分布式的执行。它们负责调度任务,协调检查点以及处理失败后的恢复。Flink集群中至少要有一个JobManager,高可用方案是配置多个JobManager,其中的一个被选择leader,其他充当standby
  • TaskManager——也被称为worker。执行数据流的任务以及缓存和交换数据流。集群中至少有一个TaskManager

    JobManager和TaskManager有多种启动方式:直接在机器上运行命令,或者在容器中或者由资源调度框架管理,比如YARN。TaskManager连接JobManager,向后者证明它们已经可用了,并且已经可以工作了。

    客户端本身不是运行时和程序执行的一部分,但被用于发送数据流给JobManager。客户端可以是一个Java程序,也可以是命令行启动的程序,比如bin/flink run....

 

任务槽和资源

    每个worker(TaskManager)是一个JVM进程,并且使用多个线程执行subtask。每个worker都会配置若干个任务槽来控制worker能够接收的最大任务数。每个任务槽代表了TaskManager的固定部分的资源。举个例子,一个TaskManager有3个槽,那么每个槽都会被分配1/3的内存。将资源划分到多个槽中意味着某个subtask并不会与其他的进行竞争,而只是使用分配给自己的内存。注意目前不支持CPU隔离,当前只是针对内存资源进行划分。

    用户通过调整任务槽数来定义subtask被隔离的方式。每个TaskManager一个槽表示每个任务组运行在一个单独的JVM中。如果有多个槽则表示同一个JVM下共享多个subtask。相同的JVM中的任务共享TCP连接和心跳消息。它们还共享数据集合和数据结构,因此也减少了任务内的开销。

    默认情况下,Flink允许subtask共享多个槽位,即使它们是属于不同task的subtask。结果就是一个槽可能保存整个任务的数据管道逻辑。槽共享有两个主要的好处:

  • Flink集群的槽位数需要和整个任务中最大的并行度相同
  • 可以获得更好的资源利用率。如果没有槽共享,source/map的subtask可能会阻塞很多资源;但如果有了槽共享,增加基础的并行度会产生更好的槽利用率,同时还能确保执行逻辑重的subtask可以被均匀地分配在TaskManager中

    Flink API同时还包含了一个资源组机制用于阻止槽位被过分滥用。比较推荐的做法是将任务槽数设置成CPU核数。特别是有了超频后,每个槽都可以执行2个或更多个硬件线程。

状态后端存储

    状态以KV索引的方式被保存在状态后端存储上,该存储既可以是内存中的hashmap,也可以是RocksDB。另外状态后端存储还需要实现逻辑以接收状态的快照并作为checkpoint的一部分进行保存。

保存点(Savepoints)

    DataStream API写成的程序是可以从一个savepoint中恢复的。Savepoints既可以更新你的程序也可以更新更新整个集群。Savepoint就是手动触发的checkpoint,对程序打快照并写入后端存储。主要还是依赖于checkpoint机制。在执行过程中,程序会在worker节点上定期打快照并创建checkpoint。在恢复时只有最新的checkpoint会被使用,而老的checkpoint可以被安全地删除。Savepoint类似于那些定期的checkpoint,只是它们是由用户触发创建的。即使产生新的savepoint,老的也不会自动地过期

展开阅读全文
打赏
0
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
0
分享
返回顶部
顶部