0

我在AWS上的雅典娜數據庫上有一個很大的數據集。我想從它並行讀取,我習慣了foreach包的方法來從分叉內R.從雅典娜(AWS)數據庫並行讀取,通過R

我使用RJDBC

這裏就是我想:

out <- foreach(i = 1:length(fipsvec), .combine = rbind, .errorhandling = "remove") %dopar% { 
    coni <- dbConnect(driver, "jdbc:awsathena://<<location>>/", 
      s3_staging_dir="my_directory", 
      user="...", 
      password="...") 
    print(paste0("starting ", i)) 
    sqlstring <- paste0("SELECT ", 
      "My_query_body" 
      fipsvec[i] 
    ) 
    row <- fetch(dbSendQuery(coni, sqlstring), -1, block = 999)   
    print(i) 
    dbDisconnect(coni) 
    rm(coni) 
    gc() 
    return(row) 
} 

(對不起,我不能讓這個重複性 - 我顯然不能用手在網上的鑰匙DB)

當我運行此,第一c = number of cores步驟來運行良好,但之後它掛起和什麼都不做 - indefi據我所知,儘可能少用。 htop在任何內核上均未顯示任何活動。當我將for循環更改爲僅循環使用c條目時,輸出結果就是我所期望的。當我從並行切換到串行(%do%而不是%dopar%)時,它也可以正常工作。

這是否與連接未被正確關閉或以某種方式被冗餘定義有關?我已將連接放置在並行循環中,因此每個核心都應該在自己的環境中擁有自己的連接。但是我對數據庫知之甚少,無法分辨這是否足夠明顯。

我會很感激的答案,幫助我理解這裏引擎蓋下發生了什麼 - 這一切對我來說都是伏都教。

回答

0

您是否將RJDBC包(以及它的依賴關係 - methods,DBIrJava)傳遞到羣集中的任何位置?

如果沒有,你對你的代碼的第一行應該類似於下面:

results <- foreach(i = 1:length(fipsvec), 
        .combine = rbind, 
        .errorhandling = "remove", 
        .packages=c('methods','DBI','rJava','RJDBC')) %dopar% { 

有一件事,我懷疑(但不知道)可能使事情有點多毛是RJDBC使用JVM執行查詢。對於rJava如何處理JVM初始化,以及每個線程是否試圖同時重新使用同一個JVM,或者如果他們有足夠的外部環境信息來正確初始化一個JVM,都不太瞭解。

如果上述操作不起作用,另一個故障排除步驟可能是將driver的分配步驟移動到%dopar%環境中。

在另一個軌道上,結果集中有多少行?如果結果集在百萬行的範圍內,並且可以通過單個查詢返回,我實際上在RJDBC包中遇到了優化的機會,並且在github上有一個公開的請求(https://github.com/s-u/RJDBC/pull/50),我沒有聽到任何信息但已經使用了我幾個月。在拉取請求中記錄了一個基本的基準,我發現加速對於我正在運行的特定查詢非常重要。

如果它似乎適用,您可以用安裝分支:

library(devtools)  
devtools::install_github("msummersgill/RJDBC",ref = "harmonize", force = TRUE) 
+0

它不是'.packages'說法。根據我的經驗,這隻對Windows機器很重要。無論如何,當我在4覈實例上循環4個條目時,並行腳本工作正常。所以每個線程都可以執行一次 - 只有一次 - 迭代。現在嘗試移動驅動程序... –

+0

另一個嘗試的步驟可能是將'.jinit(force.init = TRUE)'行作爲%dopar%環境中的第一行。 (但是我真的只是在這個時候吐口水,也不知道自己對java端的瞭解) –

+0

移動驅動程序調用也沒有幫助。現在嘗試使用'harmonize'分支 - 我試圖並行執行此操作的原因是,當嘗試將大塊讀入內存時出現錯誤。我只有大約1e5行,但我有3000列,我需要其中大部分。 –