我有一个具有 16 个内核和 8Gb ram 的 R 服务器,它初始化一个本地 SNOW 集群,例如 10 个工作人员。每个工作人员从 Microsoft SQL 服务器下载一系列数据集,将它们合并到某个键上,然后在将结果写入 SQL 服务器之前对数据集运行分析。工作人员和 SQL 服务器之间的连接通过 RJDBC 连接运行。当多个工作人员从 SQL 服务器获取数据时,内存使用量激增,R 服务器崩溃。
奇怪的是,与加载的数据集的大小相比,加载数据的工作人员使用的内存似乎不成比例地大。每个数据集大约有 8000 行和 6500 列。当保存为磁盘上的 R 对象时,这转换为大约 20MB,当保存为逗号分隔的文件时,转换为大约 160MB。然而,R 会话的 ram 使用量约为 2,3 GB。
这是代码的概述(一些印刷更改以提高可读性):
使用 RJDBC 建立连接:
require("RJDBC")
drv <- JDBC("com.microsoft.sqlserver.jdbc.SQLServerDriver","sqljdbc4.jar")
con <<- dbConnect(drv, "jdbc:sqlserver://<some.ip>","<username>","<pass>")
在此之后,有一些代码将函数输入向量requestedDataSets与要查询的所有表的名称按记录数进行排序,以便我们从最大到最小加载数据集:
nrow.to.merge <- rep(0, length(requestedDataSets))
for(d in 1:length(requestedDataSets)){
nrow.to.merge[d] <- dbGetQuery(con, paste0("select count(*) from",requestedDataSets[d]))[1,1]
}
merge.order <- order(nrow.to.merge,decreasing = T)
然后我们通过 requestedDatasets 向量并加载和/或合并数据:
for(d in merge.order){
# force reconnect to SQL server
drv <- JDBC("com.microsoft.sqlserver.jdbc.SQLServerDriver","sqljdbc4.jar")
try(dbDisconnect(con), silent = T)
con <<- dbConnect(drv, "jdbc:sqlserver://<some.ip>","<user>","<pass>")
# remove the to.merge object
rm(complete.data.to.merge)
# force garbage collection
gc()
jgc()
# ask database for dataset d
complete.data.to.merge <- dbGetQuery(con, paste0("select * from",requestedDataSets[d]))
# first dataset
if (d == merge.order[1]){
complete.data <- complete.data.to.merge
colnames(complete.data)[colnames(complete.data) == "key"] <- "key_1"
}
# later dataset
else {
complete.data <- merge(
x = complete.data,
y = complete.data.to.merge,
by.x = "key_1", by.y = "key", all.x=T)
}
}
return(complete.data)
当我在一系列十二个数据集上运行此代码时,complete.data 对象的行/列数符合预期,因此合并调用不太可能以某种方式破坏使用。对于十二次迭代, memory.size()返回 1178、1364、1500、1662、1656、1925、1835、1987、2106、2130、2217 和 2361。这又很奇怪,因为最后的数据集最多162 兆...
正如你在上面的代码中看到的,我已经尝试了一些修复,比如调用 GC()、JGC()(这是一个强制 Java 垃圾收集的函数 jgc <- function(){.jcall("java/语言/系统”,方法=“gc”)})。我也尝试过在 SQL 服务器端合并数据,但后来我遇到了列数限制。
令我烦恼的是 RAM 使用量比最终创建的数据集大得多,这让我相信存在某种缓冲区/堆溢出......但我似乎无法找到它。
任何有关如何解决此问题的建议将不胜感激。让我知道我的问题描述是否(部分)含糊不清,或者您是否需要更多信息。
谢谢。