6

各ワーカーがデータベース クエリを実行する必要がある並列タスクをセットアップしようとしています。この質問に見られるように、接続を使用して各ワーカーをセットアップしようとしていますが、試行するたびに、登録したワーカーの数が返さ<Expired PostgreSQLConnection:(2781,0)>れます。

これが私のコードです:

cl <- makeCluster(detectCores())
registerDoParallel(cl)

clusterEvalQ(cl, {
  library(RPostgreSQL)
  drv<-dbDriver("PostgreSQL")
  con<-dbConnect(drv, user="user", password="password", dbname="ISO",host="localhost")

})

foreachエラーにもかかわらず実行しようとすると、失敗しますtask 1 failed - "expired PostgreSQLConnection"

postgres サーバーのステータスに入ると、作成されたすべてのアクティブなセッションが表示されます。

メインの R インスタンスから postgres を操作するのに問題はありません。

私が走れば

clusterEvalQ(cl, {
  library(RPostgreSQL)
  drv<-dbDriver("PostgreSQL")
  con<-dbConnect(drv, user="user", password="password", dbname="ISO",host="localhost")
  dbGetQuery(con, "select inet_client_port()")

})

次に、すべてのクライアント ポートを返します。期限切れの通知は表示されませんが、 foreach コマンドを実行しようとすると、同じエラーで失敗します。

編集:

Ubuntu と 2 台の Windows コンピューターでこれを試しましたが、すべて同じエラーが発生します。

別の編集:

現在、3台のWindowsコンピューター

4

1 に答える 1

8

問題をローカルで再現できました。完全にはわかりませんが、問題はclusterEvalQ内部の仕組みに関連していると思います。たとえばdbGetQuery(con, "select inet_client_port()) 、クライアントポートの出力が得られたとします。クエリが実際にクラスター ノードで評価/実行された場合、この出力を表示することはできません (外部クラスター ノードで実行される他の出力または print ステートメントを直接読み取ることができないのと同じ方法です)。

したがって、評価は何らかの形で最初にローカル環境で実行され、その後、関連する関数と変数が個々のクラスターノードにコピー/エクスポートされると理解しています。これは、他のタイプの関数/変数では機能しますが、明らかに db 接続では機能しません。接続/ポートマッピングがマスター R インスタンスにリンクされている場合、接続はスレーブ インスタンスからは機能しません。clusterExportマスター インスタンスで作成された接続をエクスポートするために関数を使用しようとした場合も、まったく同じエラーが発生します。

foreach別の方法として、個々のタスク内に個別の接続を作成することもできます。以下が機能することをローカルデータベースで確認しました。

library(doParallel)
nrCores = detectCores()
cl <- makeCluster(nrCores)
registerDoParallel(cl)
clusterEvalQ(cl,library(RPostgreSQL))
clusterEvalQ(cl,library(DBI))

result <- foreach(i=1:nrCores) %dopar%
{
  drv <- dbDriver("PostgreSQL")
  con <- dbConnect(drv, user="user", password="password", dbname="ISO",host="localhost")
  queryResult <- dbGetQuery(con, "fetch something...")
  dbDisconnect(con)
  return(queryResult)
}
stopCluster(cl)

foreachただし、反復ごとに新しい接続を作成して切断することを考慮する必要があります。このため、パフォーマンスのオーバーヘッドが発生する可能性があります。同じ反復中に多くの作業が行われるように、クエリ/データをインテリジェントに分割することで、明らかにこれを回避できます。理想的には、使用可能なコア数と正確に同じ数の作業を分割する必要があります。

于 2015-06-28T20:22:19.337 に答える