在分布式环境下,Flink将操做的子任务链在一块儿组成一个任务,每个任务在一个线程中执行。将操做链在一块儿是一个不错的优化:它减小了线程间的切换和缓冲,提高了吞吐量同时减低了时延。这些链式行为是可配置的,详情请见:chaining docshtml
下图中的示例以5个子任务来运行,所以有5个并发的线程apache
Flink的运行时环境由两个进程组成:后端
一个Flink集群中至少有一台JobManager节点。高可用性的集群中将会有多台JobManager节点,其中有一台是leader节点,其余的是备节点(standby)。api
每个集群中至少有一个TaskManager。缓存
JobManager和TaskManager能够有多种启动方式:直接在物理机上以standalone集群的形式启动,在容器中启动以及经过资源管理框架YARN或者Mesos来启动。TaskManagers与JobManagers进行通讯,发送心跳信息来告知JobManager本身还处于活跃状态,同时接受JobManager分配的任务。数据结构
Client并非运行时环境或者程序运行的一部分,而是用来准备数据流和将数据流发送到JobManager中。以后client能够断开链接,或者继续保持链接来接收处理报告。Client要么做为触发执行的Java/Scala程序的一部分,或者是在命令行进程./bin/flink run …中并发
每个worker(TaskManager)是一个JVM进程,并在不一样的线程中运行着一个或者多个子任务。为了控制每一个worker可接受的最大任务数,每一个worker须要有个task slots(任务槽)(至少有一个槽)。每个task slot表明着TaskManager的一个固定的资源子集,例如一个TaskManager有三个slot的话,意味着该TaskManager将会分配1/3的资源到每个slot中去。将资源归入槽中意味着一个任务不会跟做业中的其余任务竞争托管内存,而是会保留必定的托管内存。注意:如今的slot尚未进行CPU的隔离,当前仅仅进行了托管内存的隔离。框架
经过调整slot的数量,用户能够自定义多少个任务之间彼此隔离。一个TaskManager有一个slot意味着每个任务运行在一个独立的JVM进程中。有多个slot意味着多个任务共享一个JVM进程,共享JVM进程的任务之间共享TCP链接和心跳信息,同时共享数据集和数据结构,从而节省了每一个任务的开销。分布式
默认状况下,Flink容许subtask(子任务)之间共享slot,即便不是来自同一个task(任务),只要这些subtask(子任务)来自同一个做业。结果是一个槽能够持有做业的整个pipeline 。容许slot共享的有两个好处:优化
一、Flink集群须要与做业中使用的最高并行度同样多的任务槽(task slot),不在须要再去计算一个程序中总共包含了多少了task(任务)。
二、使得获取更好的资源利用率变得更加容易,没有slot共享的话,非密集型的source/map子任务将会拆分红与密集型的window子任务同样多的资源。有了slot共享,就能够提升任务的并发数,从2个到6个,充分利用了槽的资源,也保证了子任务公平地分布在TaskManager集群中。
API中还包括了一个资源组机制,能够用来防止不须要的slot共享。
根据经验法则,最好的slot数量配置是跟CPU核数一致,对于超线程,每一个slot能够分配两个或者更多的硬件线程上下文。
存储key/value键值索引的切确数据结构取决于所选的state后端。一种state后端是将数据保存在内存的哈希map中 ,另外一种则是以key/value的形式保存在RocksDB中。除了定义保存State的数据结构,State后端还实现了一个逻辑来获取key/value state的时间点快照并做为checkpoint的一部分保存起来。
用DataStream API书写的程序能够从一个savepoint 中恢复执行。Savepoint容许更新您的程序而不丢失Flink中的任何state信息。
Savepoints是手动触发checkpoint,获取程序的快照并将快照写入到state后端。它们依靠按期的checkpoint机制,在执行过程当中程序在work节点上产生周期性快照,并生成checkpoint。对于故障恢复,只须要最新生成的checkpoint,旧的checkpoint能够在新的checkpoint生成以后就丢弃掉了。
Savepoints相似于周期性的checkpoint,除了它们是由用户手动触发的,而且不会在新的checkpoint生成以后而自动过时。Savepoints能够经过命令行生成或者在取消一个做业时调用REST API产生。