问题思考?
- 官网中flink架构图,flink中默认TaskManager是分配一个slot,对应一个jvm
- 如果一个TaskManager分配三个slot线程,并且3个slot分别执行了不同job的算子任务,根据官网描述可以共享“数据集和数据结构”,且按照我们日常编码,一个jvm实例内的不同线程,是共享jvm中的共同的成员变量以及类包的,那么显然如果这样flink执行任务会发生紊乱,所以flnk是怎么做的?:
flink中一个jvm内共享了什么数据集,数据结构? 不同job任务可能存在同全类名的类,甚至同一个项目包的类,加载到一个jvm中怎么做到互相隔离,成员变量互不影响?
源码解析
org.apache.flink.runtime.taskmanager.Task#doRun org.apache.flink.runtime.execution.librarycache.LibraryCacheEntry#LibraryCacheEntry org.apache.flink.runtime.taskmanager.Task#doRun 可以看到task获取到任务之后
- 下载任务代码
- 新建任务线程的类加载器
- 任务线程所有类使用新建的类加载器
- 显然,slot共享的数据结构就是flink框架启动提前已经加载的公共类,比如tcp连接相关的类,slotTable缓存等【双亲委派机制】
那么问题就清晰了,因为不同的类加载器有独立的类名称空间,即使来自同一个class文件,如果类加载器不一样,那么就是不同的类,因此不同task的代码运行在同一taskmanager上,即使有相同的class文件加载,也互相隔离,实际上这也是所有web容器框架都需要解决的问题。
结论
参考《深入理解jvm》 类加载器对instance of 的影响,代码例子如下:
|