Flink类加载
flink类加载相关的配置参数
- classloader.check-leaked-classloader : true 如果一个作业的用户类加载器在作业终止后使用,则装入类的尝试将失败。这通常是由滞留线程或行为不当的库泄漏类加载器造成的,这也可能导致其他作业使用类加载器。只有当泄漏阻止了进一步的作业运行时,才应该禁用此检查
- classloader.fail-on-metaspace-oom-error : true 如果在尝试加载用户代码类时抛出’OutOfMemoryError: metspace ‘,则Flink JVM进程失败。
- classloader.parent-first-patterns.additional :None 一个(分号分隔的)模式列表,指定哪些类应该首先通过父ClassLoader解析。模式是根据完全限定类名进行检查的简单前缀。这些模式被附加到“classloader.parent-first-patterns.default”中。
- classloader.parent-first-patterns.default 一个(分号分隔的)模式列表,指定哪些类应该首先通过父ClassLoader解析。模式是根据完全限定类名进行检查的简单前缀。一般不应修改此设置。要添加另一个模式,建议使用“classloader.parent-first-patterns.additional”。增加额外需要优先从Flink集群加载的类
- classloader.resolve-order : “child-first” 定义从用户代码加载类时的类解析策略,即首先检查用户代码jar(“child-first”)还是应用程序类路径【application classpath】(“parent-first”)。默认设置指示首先从用户代码jar加载类,这意味着用户代码jar可以包含和加载不同于Flink使用的依赖项(传递)。
FlinkUserCodeClassLoader是一个继承了URLClassLoader的抽象类,主要约束子类加载器在进行类加载的一些行为。
ParentFirstClassLoader类加载器的实现特别简单,仅仅是一个继承FlinkUserCodeClassLoader的空类而已,通过指定的URL数组加载类,用于优先加载application classpath下的类,利用双亲委派模型实现了parent-first的类加载机制
ChildFirstClassLoader类加载器 :
- 首先判断类是否加载,
- 如果未加载
- 针对classloader.parent-first-patterns.default 及 classloader.parent-first-patterns.additional中定义的类,委托父类进行加载,
- 其它类,避开了“先把加载的请求委托给父加载器完成”这一步骤,先自己加载【在用户代码中查找并获取该类的定义】,只有在加载失败时则委托父类进行加载
具体任务执行时的类加载:
TaskManager在要执行具体的任务之前,都是通过submitTask()方法得到具体所要执行的任务。
在submitTask()中,部署的任务信息并不包含具体所要执行的目标任务类jar包。
- 所有任务的抽象是Task类。实现了Runnnable接口,提供了run()方法可提供给线程进行调用。
- 在其构造方法中,以自身为target作为Thread构造函数的参数,得到可执行的线程对象,具体代码参见:TaskExecutor中的CompletableFuture submitTask(TaskDeploymentDescriptor tdd, JobMasterId jobMasterId, Time timeout)
- 在Task()的构造方法,只给出了job的执行类名和和blob类型的jar包名和classpath名
- 在Task的run()方法中【具体在doRun()方法中】也将根据这些信息加载得到目标任务的实现类并执行。
- 首先,会通过createUserCodeClassLoader()方法去得到目标任务类的类加载器。
- 在这个方法中涉及到了libraryCacheEntry。libraryCacheEntry是一个LibraryCacheEntry类型的对象.。 LibraryCacheManager用来缓存下载得到的目标jar包,具体实现类为BlobLibraryCacheManager。
- 在构造ResolvedClassLoader对象时,通过createUserCodeClassLoader 确保执行任务的对应jar包下载完毕之后,根据jobid得到对应的类加载器,即可准备加载相应的任务类,执行相应的类。
- 通过loadAndInstantiateInvokable()方法加载并实例化目标类。
- 通过得到的类加载器加载相应的类,并取得envirment为参数的构造方法,通过该构造方法实例化一个类 ,作为Task中实际被调用的类的实例,接下来将准备被正是调用