《基于 Apache Flink 的流处理》阅读笔记(二)
Apache Flink架构
-
运行时架构:四个JVM进程运行在不同的物理节点上
-
JobManager:
- 主进程控制单个应用程序执行,每个应用程序都有一个JobManager进行控制
- 包括:JobGraph(Dataflow图,执行时转化为物理Dataflow图)+ 类库资源的 JAR 包
- 根据物理 Dataflow 图(ExecutionGraph)向 ResourceManager 申请资源(就是槽 slots),然后分发运行
- 运行中协调操作,协调 checkpoint,协调恢复,至少要有一个 JobManager
-
TaskManager
-
工作进程;包含多个线程——slots 作为资源进行分配
-
slots 向 ResourceManager 注册,JobManager申请就能够分配
-
slots 对应着运行并行度
设置taskslot的时候推荐的就是设置为CPU的核数(虽然隔离的是内存,共享的是CPU,这样安排是因为避免各个slot之间共享CPU导致的CPU繁忙)
并行度parallelsim和slots的关系是动态和静态的关系:也就是说,例如三个taskmanager(一个taskmanager就是一个JVM进程)设置taskslot = 3 ,这样就有9个taskslots,也就是9个线程;这时在运行的时候设置parallelism是1,就是用了一个slot执行整个任务
其中每个算子都能够设置并行度,但如果想要设置全局的并行度,就使用env.setParallism 就行
如果总体也设置了并行,算子也设置了并行,这时候算子的并行设置的优先级高
-
-
ResourceManager
- 管理 TaskManager 中的slots,管理申请和使用完的释放管理
-
Dispatcher
- 接收提交的应用,启动JobManager对应这个应用
-
-
部署的方式
- 框架模式:Flink应用打成一个JAR包提交运行
- 库模式:Flink应用和容器镜像绑定,微服务架构中使用(Docker)
-
任务执行
-
左侧就是一个逻辑Dataflow图,右侧就是设置并行度之后的实际运行的物理分布,不同并行度的算子实例在不同的slot里面;这里E算子的并行度就是2,D并行度就是4
-
这里TashManager这个JVM进程同时运行着多个线程
-
每个子任务(或者子任务任务量小的时候组成的任务链,也就是说子任务可以共享slot的)就会分配到不同的单个slots中有的时候会把sink设置成单并行度,因为这样写文件的时候不会有多个操作者造成并行写问题
-
故障处理
- 上述的不同组件遇到故障的处理:HA模式部署多个JobManager,借助ZooKeeper
-
数据通信
- 不同的组件运行在各自的JVM进程中,TaskManager之间会有一个或者多个TCP连接
-
接收端1要接收四个输入,就要有四个缓冲区
-
同一个进程内任务线程之间不需要网络通信
-
缓冲区会带来延时,所以对应的机制
- 基于信用值的流量控制:发送端根据信用值尽最大发送缓冲的数据,降低了逐条发送的延时
- 任务链将多个任务链接起来放到同一个slots中,减少了网络开销;例如将一个Dataflow设置成并行度为1,这样就形成了一个任务链
-
Flink中的时间语义(两种都要有)
- 时间戳:数据记录和对应时间,8B的 Long 类型对时间戳编码,附在记录上
- 来源:DataStream的SourceFunction
- 水位线:
- 来源:DataSteam中的方法
- Long时间戳的一种特殊记录,和普通数据记录一起在数据流中
- 单调递增的;一个时间戳是T的水位线表示小于等于T的所有记录都到了,用于触发计算操作,水位线越接近普通记录的时间戳,就表明延时越小,因为等待的记录数量会变少,但是完整性会降低,因为很有可能有迟到的
- 算子实例内部设置:事件服务 + 计时器,依靠水位线**;
- 并行执行的数据流都有带有时间戳的记录和水位线,一个算子实例可能就会由多个数据流的输入,水位线就有对齐的问题
- 算子实例中不同数据流各自的分区水位线:来一个分区的水位线更新一下,然年发送当前最小的到下游;同时事件事件时钟更新,保留单值,所以不同数据流的记录会按照同一个时间进行触发处理
- 时间戳:数据记录和对应时间,8B的 Long 类型对时间戳编码,附在记录上