Flink运行架构
flink程序结构
flink程序的基本构建是流和转换。底层无论是批处理还是流处理都当作是流处理。
source
数据源,flink在流处理和批处理上的source大概有4类,基于本地集合的source 基于文件的source 基于网络套接字的source 自定义的source。
自定义的source常见的有kafka,mq等,当然也可以定义自己的source
transformation
数据转换的各种操作,有map/flatmap/filter/keyby/reduce/fold/aggregations/window/windowAll/union/window join/split/select等,操作很多,把数据转换计算成为你想要的数据
sink
接收器,flink将转换计算后的数据发送的地点,需要存储起来,flink上见的sink大概有几类,写入文件,打印出来,写入socket 自定义sink
flink并行数据流
flink程序在执行的时候,会被映射成为streaming dataflow ,一个streaming dataflow是由一组stream 和 transformation operator组成的,在启动的时候,从一个或者多个source operator开始,结束于一个或者多个sink operator
flink程序本质上是并行的和分布式的,再执行过程中,一个流stream包含一个或多个流分区,而每一个operator包含一个或者多个operator子任务,操作子任务间彼此独立,在不同的线程中运行。甚至是不同的机器或者不同的容器上。
数据在两个operator之间传递的时候有两种模式
one to one 模式:两个operator用此模式传递的时候,会保持数据的分区和数据的排序,source1到map1,就保留分区的特性。
redistributing(重新分配模式):这种模式会改变数据的分区数,每个一个operator subtask会根据选择transformation把数据发送到不同的目标subtasks,比如keyby()会通过hashmap重新分区,broadcast()和rebalance()方法会随机重新分区。
task和operator chain
flink的所有操作都称之为operator,客户端在提交任务的时候会对operator进行优化操作,能进行合并的operator会被合并为一个operator,合并后的operator称为operator chain,实际上就是一个执行链,每个执行链会在taskmanager上的一个独立的线程中执行。
flink任务调度和执行
程序代码 -> 优化器图生成器 -> Akka客户端
提交作业到,发送数据流图到jobmanager
jobmanager中有actorsystem ,还有调度器和checkpoint协调器
在发送到taskmanager中,每个taskmanager有slot,slot中运行的是任务。
1)flink执行executor会自动根据程序生成代码DAG数据流图
2)ActorSystem创建Actor将数据流图发送给jobmanager中的Actor
3)jobmanager会不断的接受taskmanager的心跳消息,从而可以获取到有效的taskmanager
4)jobmanager通过调度器在taskmanager中调度task,在flink中,最小的调度单元就是task,对应的就是一个线程
5)在程序运行的时候,task与task之间是可以进行数据传输的
任务槽(task-slot)和槽共享(slot sharing)
每个taskmanager是一个jvm的进程,worker通过task slot来进行控制一个(一个worker至少有一个task slot)
slot是flink从资源层面进行调度的单位
特点:slot是会平均划分当前tm的内存,flink程序的最大并行度,就是所有tm中的数量,我们flink可以控制接受的任务数量就是通过slot数量还实现
slot的数量如何确定:保持和tm中的cpu核数一样,保证任务的执行
slot实际上是任务执行的真正角色
slot sharing槽共享
每个slot都可以接收当前作业的不同的子任务,这样充分利用了当前所有的slot来提高并行度