2012年11月17日星期六

从Java里调用R – 使用Rserve


从Java里调用R – 使用Rserve

简介

前段时间介绍了在Java中设置与使用JRI的方法。这种方式有一些弊端:
  • R需要与JVM运行在同一台机器上,当R需要运行大型计算时,会耗用大量CPU与内存,因此会影响到JVM的性能
  • JRI的设置需要本地库的支持,运行的时候还是有些麻烦的
Rserve可以解决这两个问题,同时也有JRI一样的易用性。它的原理是提供以HTTP方式连接的R语言接口, 因此可以让专门一台机器来运行RServe,然后让Java或其它语言的客户端来进行连接。额外的好处是,可以支持Java在内的多种客户端。
Rserve推荐在Linux下使用,因为在Windows平台上还很不完善(下面会介绍)。但由于多数程序员还是习惯于在Windows环境下进行开发,还是有必要找到在Windows上进行它的办法。这篇文章主要介绍这个环境的话题。

安装RServe

以下以Windows平台为例介绍安装的方法。Rserve可以从其网站下载单独安装,但更方便的方式是从R中直接进行安装,只需运行
install.packages(‘Rserve’)
然后,需要手动复制$R_HOME/library/rserve/Rserve*.exe到bin/i386里(视平台而定)。
运行时,在命令行输入:
R CMD Rserve
你会得到它成功运行的提示。
要想关闭服务,最好的方法是从任务管理器里直接杀死rserve.exe进程。我发现在命令行窗口按Ctrl-C似乎有时并不能成功关闭服务, 这个很奇怪。

使用与局限

Windows上运行Rserve还是有很大的局限性的。
最大的问题是,所有的连接都会在一个工作空间内运行。所以当客户端是多线程程序时,可能会造成线程间互相干扰。我们需要在客户端做一些额外的工作,使它能够以线程安全的方式运行。Java端可以通过使用synchronize使得同一时间只有一个线程使用R服务。
Rserve的另一个缺点是,它的错误处理过于简单化,如果R端出现错误,它抛出的异常对于找到问题的根源几乎没有任何用处。所以我建议R端的程序一定要多写LOG,或以统一的方式处理异常。
其次,开发中需要注意的是,Rserve同时只允许一个客户端连接。因此,如果第二个线程试图连接时,它就会一直处在等待状态。另外,如果要更新R包,也需要关闭并重新启动Rserve。所以,如果发现客户端连接时出现异常情况,查看一下任务管理器,看是不是有多个Rserve的线程在运行,或者你的服务有没有重启,往往可以帮助解决问题。
以下源码是一个使用Rserve实现线程安全的R服务的Java客户端。包含了用Spring配置的RService对象, 以及相关的TestNG的测试。下载后需要做一些配置和修改才能使用,不过东西比较简单,主要是演示这个idea。
源码下载:RService.zip

示例

以下Java代码演示了使用上面zip包中的R服务对象来调用R语言来生成图形的方法。
RService rService = new RService();
RConnection re = rService.startTransaction(); //开始独占工作空间
 
double[][] xx = ...; //生成两个二维数组
double[][] yy = ...;
 
File tempFile = null;
try {
    re.assign("x", xx); //给R的变量赋值
    re.assign("y", yy);
    tempFile = File.createTempFile("test-", ".jpg"); //把图像生成到文件
    String filePath = tempFile.getAbsolutePath();
    logger.info("Plot file to be produced:" + filePath);
    re.eval("jpeg('" + StringEscapeUtils.escapeJava(filePath) + "')");
    re.eval("qqplot(x,y)"); //绘图
    re.eval("dev.off()");
} catch (IOException e) {
    logger.warn("Failed to create temp file", e);
} finally {
    this.rService.endTransaction(); //退出时一定要关闭此工作空间
}
Rserve网站已经移到RForge上:http://www.rforge.net/Rserve/
About Fan
从事软件行业多年,关心软件工程与技术、项目管理、数据统计与分析、BI、Java软件开发。


没有评论:

发表评论