Подключение ROracle на рабочих узлах // Автоматическая отчетность с R Markdown

Я столкнулся с несколькими явными проблемами, пытаясь ускорить автоматическое создание отчетов для большого набора данных. Я использую 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, они кажутся в порядке ...

Далее основная функция вызывает цикл для генерации отчета.

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, хотя я недостаточно знаю об этом предмете, чтобы действительно точно определить проблему.

Если у кого-то был подобный опыт или есть подозрение о том, что происходит, любой совет будет оценен!

Дайте мне знать, если я смогу что-нибудь уточнить ...

Спасибо


person Erik    schedule 04.08.2015    source источник


Ответы (1)


Проблема решена с помощью различных хаков. Во-первых, основной цикл был переписан для извлечения данных в локальный сеанс R вместо выполнения SQL в отчете по уценке. Казалось, что это помогло устранить некоторые конфликты при подключении к базе данных, но не устранило это полностью. Итак, я добавил некоторые функции tryCatch () и repeat () к функциям, которые запрашивали данные или пытались подключиться к dB. Настоятельно рекомендую всем, у кого есть проблемы с ROracle в кластере, реализовать нечто подобное и тратить время на просмотр сообщений об ошибках, чтобы узнать, что именно происходит.

Далее в вопросах с преобразованием pandoc. Большинство проблем было решено путем разрешения соединения с устаревшей таблицей в SQL (в старой таблице не хватало данных для некоторых групп, поэтому не было ни одной строки, и отчет не создавался). Тем не менее, некоторые проблемы все еще оставались, когда rmarkdown :: render () выполнялся успешно, но фактический результат был бы пустым или поврежденным. Понятия не имею, что вызвало эту проблему, но способ, которым я ее решил, заключался в том, чтобы сравнить размеры файлов сгенерированных отчетов (пустые составляли ~ 300 КБ, завершенные 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 и repeat в случае ошибок.

Оборачивать вызовы rmarkdown :: render () с помощью функций tryCatch и repeat и регистрировать статус, размер файла, имя файла, расположение файла и т. д.

--Загрузите файл журнала, созданный, как указано выше, из вызовов rmarkdown :: render, найдите размеры файлов с выбросами (в моем случае просто Z-значения размера файла, отфильтруйте их с помощью ‹- 3) для выявления отчетов, в которых все еще существуют проблемы. Сделайте что-нибудь, чтобы исправить их повторный запуск на одном рабочем месте

В целом, ~ 4500 отчетов сгенерированы из подмножества моих данных, время работы на 4 ядрах i5 с частотой 2,8 ГГц составляет около 1 часа. Общее количество созданных «плохих» отчетов составляет около 1% от общего числа.

person Erik    schedule 11.08.2015