【问题标题】:ROracle Connection on Worker Nodes // Automated reporting with R Markdown工作节点上的 ROracle 连接 // 使用 R Markdown 自动报告
【发布时间】:2015-10-26 23:53:44
【问题描述】:

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

系统主要由两部分组成

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

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

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 的集群节点中的连接对象有关,尽管我对主题的了解不够,无法真正查明问题。

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

如果我可以澄清任何事情,请告诉我...

谢谢

【问题讨论】:

    标签: r oracle foreach doparallel roracle


    【解决方案1】:

    问题已通过各种 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 尝试在实现 tryCatchrepeat 功能的函数内部以防出错

    使用 tryCatchrepeat 功能以及记录状态、文件大小、文件名、文件位置等来包装对 rmarkdown::render() 的调用。

    --从 rmarkdown::render 调用加载如上创建的日志文件,查找 异常文件大小(在我的情况下,只是文件大小的 Z 分数,过滤那些

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-03-17
      • 1970-01-01
      • 2018-07-05
      • 1970-01-01
      • 2021-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多