博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
JPPF并行计算框架类加载机制研究
阅读量:7067 次
发布时间:2019-06-28

本文共 3091 字,大约阅读时间需要 10 分钟。

hot3.png

JPPF并行计算框架类加载机制研究 博客分类: java

不算什么深入的研究,主要是了解下JPPF中类的加载和隔离机制。

JPPF中类的加载采用的是分布式类加载技术。这样既可在Node节点运行在node上并不存在的类。也就是类可以仅在用户的Client端存在。

 

如图,JPPF的class loader大致分三层。

System class loader是由JVM控制的加载器,用于启动node节点。在大多数JVM中是,该loader是java.net.URLClassloader的实例。
Server class loader是类AbstractJPPFClassloader的实现,提供了远程访问server端classpath中的类和其他资源的功能。该loader在node连接到server端的时候创建,断开连接的时候销毁。其父loader为System class loader。
Client class loader也是AbstractJPPFClassloader类的实现,提供了远程访问一个或多个客户端上的类和资源的功能。该loader在客户端提交任务的时候创建。一个node可能会持有很多client class loader。

JPPF的node节点仅持有一个与Server的连接,该连接被所有的loader共享,这样可以避免并发时潜在的的一致性,同步和冲突等问题。

Java的classloader是先从parent loader开始加载的饿,下图展示了node节点加载类的过程

 

 

node节点先从server节点请求class。如果server节点存在class,则直接加载返回。

如果class仅在client端存在,则会先访问server,server无,再通过server定位client,访问client端的class。

在JPPF框架里,每个client都有一个唯一的UUID,用于唯一标识该client。Node节点便可根据此UUID识别出当前classloader读取的是哪个client的class

每个Server也有唯一的UUID标识,这样就可以实现链式类加载:

 

需要注意的是,在这种情况下,node节点仍然只持有一个server classloader,仅连接跟它直接关联的server。

UUID与classloader

使用client端UUID,即可实现不同的client端在执行同一个任务的时候的classloader隔离,因为uuid不同,会使用不同的classloader加载类。不过,如果同一个UUID提交了两个不同版本的任务class,则有可能出现冲突和错误。    
你也可以手动指定client端的UUID,这样classloader即可重用。哪怕你重连client也可以重用同一个classloader。不过,此时随之而来的问题就是在客户端修改的版本可能不会在node端自动生效,不同的版本还可能造成冲突。这时,你可以重启node或者更换UUID使node重新加载class。

任务预部署

对于大任务,如果担心每次走网络效率低,根据上面介绍的classloader机制,自然想到可以预先将任务文件部署到server或者node节点。不过此时需要自己管理好部署的版本,所谓各有利弊。不过,如果任务版本稳定的话,建议采用此种方式。

classloader缓存池

为了避免加载过多的类造成内存溢出,JPPF在node端增加了classloader缓存池大小的设置,如果超过上限,则会销毁最老的classloader。

jppf.classloader.cache.size = n

 

本地缓存资源文件

当调用getResourceAsStream(),  getResource(),getResources() or getMultipleResources()方法的时候,class loader会缓存非类定义的文件至内存或者本地文件系统中。这样会避免再次请求该文件时候的网络访问,提高效率。你可以指定缓存在内存中还是文件系统中:

# either “file” (the default) or “memory“

jppf.resource.cache.storage = file

 

文件的保存路径当然也是可以配置的,默认是系统临时文件夹System.getProperty("java.io.tmpdir").:

jppf.resource.cache.dir = some_directory

 

JPPF server中的类缓存

JPPF的服务端会在内存中缓存被classloader加载进来的类和其他资。这样就可以避免与客户端的频繁的网络访问,从而提高执行速度。你也无需担心内存溢出的问题,因为这种缓存采用的是软引用,这样缓存的类就可以在必要的时候被JVM的垃圾回收机制回收。在一般情况,该缓存还是可以显著的提升效率的。

Class loader代理模型

JPPF默认采用的是”父优先“的类加载模型,也就是上面我们介绍的模型。上述模型虽然好用,但是类的加载顺序就相对固定,也就不能最大化的优化加载效率。因此,JPPF通过继承URLClassLoader,复写并开放addURL接口(jdk里是protected,JPPF为public),使得用户的自己开发任务可以直接调用该方法,形成对classloader的一种扩展。用户可调用addURL方法,指定自己想要加载类的地址。此时JPPF classloader的加载顺序会出现变化,从大的步骤看,会先查找指定的URL classpath:

* 从clientclassloader入手:代理到server的classloader

* server的classloader: 先仅查找用户指定的URL classpath
* 如果找到类,则结束查找
* 否则,回到client的classloader,也仅查找URL的classpath
* 如果找到,结束查找。

 

此书,如果仍未找到,则回到前面介绍的通过网络的查找顺序。

概括来说,就是如果URL优先的代理模型激活,则node会先从本地层级中查找URL指定的classpath,然后在网络上通过server查找。有三种指定代理模型的方式,最简单的就是直接配置在node节点的配置文件中:

  # possible values: parent | url, defaults to parent

  jppf.classloader.delegation = parent

 

下载文件

如我们之前的介绍的,我们可以通过addURL(URL)方法,动态指定加载类的URL地址,那么自然想到,我们可以通过先将文件下载到本地,然后指定URL地址,从而进行本地加载,以提到效率。在AbstractJPPFClassLoader类中,有方法:

public URL[] getMultipleResources(final String…names)
可以帮你同时下载多个文件到本地。

以上只是我了解到的JPPF中关于类加载部分的设计和实现。从已有掌握来看,JPPF考虑的还是非常全面周到的,隔离、效率、一致性都有考虑,应该说对并行计算来说,很有保障。

 

转载至:http://www.coderli.com/jppf-classloader

 

转载于:https://my.oschina.net/xiaominmin/blog/1597978

你可能感兴趣的文章
VMware Horzion Workspace POC文档--安装2(集成VIEW)
查看>>
lvs-NAT模式的实现
查看>>
Tomcat ssl 实现
查看>>
人生感悟 --有理想的程序员必须知道的15件事
查看>>
浅谈HDFS的读流程
查看>>
我是如何入门、成长并进阶为数据分析师的?
查看>>
【探索】VS下虚继承实现的方法-1
查看>>
Java基础加密之MD5加密算法
查看>>
盛夏光年
查看>>
Android 沉浸式状态栏(像IOS那样的状态栏与应用统一颜色样式)
查看>>
指针、动态分配与链表
查看>>
RHCS集群服务 7.10
查看>>
windows 使用vnc图形化界面远程连接阿里云ubuntu 16.04云服务器
查看>>
linux和CentOS是什么关系;CentOS和RHEL是什么关系
查看>>
samba
查看>>
myeclipse+maven搭建web项目方法一(超级详细)
查看>>
利用Python网络爬虫抓取微信好友的签名及其可视化展示
查看>>
Linux-Nginx代理
查看>>
计算机的系统组成简介---运维笔记
查看>>
Liunx nginx 的使用方法及模块
查看>>