2

在尝试加速大型数据集的一些自动报告生成时,我遇到了几个不同的问题。我正在使用 R + markdown -> HTML 来生成报告,并循环访问约 10K 不同的分组,以便报告访问来自 Oracle 的数据。

该系统主要由两部分组成

  1. 一个主脚本
  2. 一个降价模板文件

主脚本设置计算环境和并行处理后端:

library(ROracle)
library(doParallel) ..etc
....
cl <- makeCluster(4)
clusterEvalQ(cl, con<-dbConnect(db,un,pw)) ##pseudocode...

这里似乎出现了第一个问题。R 抛出一个异常,指出工作人员上的连接无效但是当我在 Oracle 上监视实时会话时,它们似乎很好......

接下来,main 调用循环生成报告。

foreach(i=1:nrow(reportgroups), .packages=c('ROracle', 'ggplot2', 'knitr') %dopar% ##...etc 
{
    rmarkdown::render(inputfile.Rmd, outputfile.html, params=list(groupParam1[i], groupParam2[i], etc)
}

如果我按顺序运行 foreach 循环,即 %do% 而不是 %dopar%,一切似乎都运行良好。没有错误,然后整套运行正确(我只测试了约 400 组,将在一夜之间完成所有 10k 的完整运行)。

但是,如果我尝试并行运行循环,“pandoc”在转换文件时总是会抛出错误 #1。如果我多次运行损坏的循环,循环中的“任务”(或集群,不确定在此上下文中指的是哪个任务)会导致错误发生变化。

模板文件非常基本,它接受组参数,在为集群工作者定义的连接上运行 SQL 查询,并利用 ggplot2 + dplyr 生成结果。由于模板似乎在不通过集群时运行,我认为问题一定与来自 ROracle 的集群节点中的连接对象有关,尽管我对主题的了解还不够,无法真正查明问题。

如果有人有类似的经历,或者对正在发生的事情有预感,任何建议都将不胜感激!

如果我能澄清什么,请告诉我...

谢谢

4

1 回答 1

0

问题已通过各种 hack 解决。首先,重写主循环以将数据拉入本地 R 会话,而不是在降价报告中运行 SQL。这似乎有助于解决与数据库连接中的一些冲突,但并没有完全解决它。因此,我在查询数据或尝试连接到 dB 的函数中添加了一些 tryCatch() 和 repeat() 功能。强烈建议任何在集群上遇到 ROracle 问题的人实施类似的方法,并花时间查看错误消息以了解究竟发生了什么。

接下来,关于 pandoc 转换的问题。大多数问题都是通过在 SQL 中解决与折旧表的连接来解决的(旧表缺少某些组的数据,因此没有提取任何行并且不会生成报告)。但是,在 rmarkdown::render() 可以成功运行的地方仍然存在一些问题,但实际输出将为空或损坏。不知道是什么导致了这个问题,但我解决它的方法是比较生成的报告的文件大小(空的是 ~ 300kb,完成的是 400 + )并在集群关闭后重新运行报告生成在一台机器上. 这似乎解决了任何最后的问题。

总之:

以前:生成的报告,但存在重大问题和不完整的数据。

修复:

对于集群,请确保多次尝试连接到 dB,以防运行期间出现问题。抓取数据后不要忘记关闭连接。在 ROracle 中,创建驱动程序,即

driver <- dbDriver("Oracle")

是连接数据库最耗时的部分,但驱动程序可以在循环中通过多个连接重用,例如,

##Create driver outside loop, and reuse inside
for(i in 1:n){
    con <- dbConnect(driver, 'username', 'password')
    data <- dbGetQuery(con, 'Select * from mydata')
    dbDisconnect(con)
    ...##do something to data
}

比打电话要快得多

dbConnect(dbDriver("Oracle"), 'username', 'password')

循环内

将连接 / sql 尝试包装在一个函数中,该函数实现tryCatch并在出现错误时重复功能

使用 tryCatch 包装对 rmarkdown::render()调用重复功能和记录状态、文件大小、文件名、文件位置等。

--从rmarkdown::render调用中加载如上创建的日志文件,查找异常文件大小(在我的情况下,只是文件大小的 Z 分数,过滤具有 < -3 的文件)以识别仍然存在问题的报告。做一些事情来修复它们在单个工人身上重新运行

总体而言,从我的数据子集生成了约 4500 份报告,在 4 核 i5 @ 2.8 Ghz 上的时间约为1 小时。生成的“不良”报告总数约为总数的 1%。

于 2015-08-11T07:46:43.090 回答