使用parLapply将数据帧写入Oracle数据库时出现JVM错误

时间:2019-01-15 06:23:56

标签: java r parallel-processing doparallel rjdbc

我想并行化数据写入过程。我正在向Oracle数据库编写数据框架。该数据具有400万行和8列。不进行并行化需要6.5个小时。

当我尝试平行运行时,出现错误

Error in checkForRemoteErrors(val) : 
  7 nodes produced errors; first error: No running JVM detected. Maybe .jinit() would help.

我知道这个错误。当我使用单个群集时,我可以解决它。但是我不知道如何告诉其他集群Java的位置。这是我的代码

Sys.setenv(JAVA_HOME='C:/Program Files/Java/jre1.8.0_181') 
library(rJava)
library(RJDBC)
library(DBI)
library(compiler)
library(dplyr)
library(data.table)

jdbcDriver =JDBC("oracle.jdbc.OracleDriver",classPath="C:/Program Files/directory/ojdbc6.jar", identifier.quote = "\"") 
jdbcConnection =dbConnect(jdbcDriver, "jdbc:oracle:thin:@//XXXXX", "YYYYY", "ZZZZZ")

通过使用Sys.setenv(JAVA_HOME='C:/Program Files/Java/jre1.8.0_181'),我可以为单核解决相同的问题。但是当我平行进行时

library(parallel)
no_cores <- detectCores() - 1
cl <- makeCluster(no_cores)
clusterExport(cl, varlist = list("jdbcConnection", "brand3.merge.u"))
clusterEvalQ(cl, .libPaths("C:/Users/onur.boyar/Documents/R/win-library/3.5"))
clusterEvalQ(cl, library(RJDBC))
clusterEvalQ(cl, library(rJava))

parLapply(cl, 1:length(brand3.merge.u$CELL_PH_NUM), function(x) dbSendUpdate(jdbcConnection, "INSERT INTO xxnvdw.an_cust_analytics  VALUES(?,?,?,?,?,?,?,?)", brand3.merge.u[x, 1], brand3.merge.u[x,2], brand3.merge.u[x,3],brand3.merge.u[x,4],brand3.merge.u[x,5],brand3.merge.u[x,6],brand3.merge.u[x,7],brand3.merge.u[x,8]))

#brand3.merge.u is my data frame that I try to write.  

出现上述错误,我不知道如何为其他节点设置Java位置。

我想使用parLapply,因为它比foreach更快。任何帮助,将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:1)

JAVA_HOME环境变量

如果问题确实出在Java的位置,则可以在.Renviron文件中设置环境变量。它可能位于~/.Renviron中。在该文件中添加一行,该行将传播到通过您的用户运行的所有R会话中:

JAVA_HOME='C:/Program Files/Java/jre1.8.0_181'

或者,您也可以add that location to your PATH个环境变量。

通过rJava初始化JVM

另一方面,错误消息可能指向未初始化的JVM,您可以使用.jinit解决此问题,这是一个最小的示例:

library(parallel)
cl <- makeCluster(detectCores())
parallel::parLapply(cl, 1:5, function(x) {
  rJava::.jinit()
  rJava::.jnew(class = "java/lang/Integer", x)$toString()
})

解决Java使用问题

没有特别要求,但是您也可以使用ODBC驱动程序来解决Java依赖的需求,对于Oracle,应使用accessible here

con <- DBI::dbConnect(
  odbc::odbc(),
  Driver = "[your driver's name]",
  ...
)