Amazon Elastic MapReduceでのRマッパースクリプトのトラブルシューティング - 予想どおりではない結果
-
10-10-2019 - |
質問
私は使用しようとしています Amazon Elastic Mapが減少します 数百万件の一連のシミュレーションを実行します。これは、還元剤のないrscriptストリーミングジョブです。私は私のEMRコールでアイデンティティ減少者を使用しています --reducer org.apache.hadoop.mapred.lib.IdentityReducer
.
スクリプトファイルは、テストされたときに正常に動作し、1本の文字列を手動で渡すときにLinuxボックスのコマンドラインからローカルに実行されます echo "1,2443,2442,1,5" | ./mapper.R
そして、私が期待している一連の結果を得ます。ただし、EMRの入力ファイルから約10,000のケース(行)を使用してシミュレーションをテストしたとき、10K入力ラインのうち12行ほどの出力しか得られませんでした。何度か試してみましたが、その理由を理解できません。 Hadoopジョブは、エラーなしで正常に実行されます。入力ラインがスキップされているように見えます。または、ID削減剤で何かが起こっているようです。結果は、出力がある場合には正しいです。
私の入力ファイルは、次のデータ形式を備えたCSVであり、コンマで区切られた5つの整数のシリーズです。
1,2443,2442,1,5
2,2743,4712,99,8
3,2443,861,282,3177
etc...
これが私のRスクリプトです Mapper.R
#! /usr/bin/env Rscript
# Define Functions
trimWhiteSpace <- function(line) gsub("(^ +)|( +$)", "", line)
splitIntoWords <- function(line) unlist(strsplit(line, "[[:space:]]+"))
# function to read in the relevant data from needed data files
get.data <- function(casename) {
list <- lapply(casename, function(x) {
read.csv(file = paste("./inputdata/",x, ".csv", sep = ""),
header = TRUE,
stringsAsFactors = FALSE)})
return(data.frame(list))
}
con <- file("stdin")
line <- readLines(con, n = 1, warn = FALSE)
line <- trimWhiteSpace(line)
values <- unlist(strsplit(line, ","))
lv <- length(values)
cases <- as.numeric(values[2:lv])
simid <- paste("sim", values[1], ":", sep = "")
l <- length(cases) # for indexing
## create a vector for the case names
names.vector <- paste("case", cases, sep = ".")
## read in metadata and necessary data columns using get.data function
metadata <- read.csv(file = "./inputdata/metadata.csv", header = TRUE,
stringsAsFactors = FALSE)
d <- cbind(metadata[,1:3], get.data(names.vector))
## Calculations that use df d and produce a string called 'output'
## in the form of "id: value1 value2 value3 ..." to be used at a
## later time for agregation.
cat(output, "\n")
close(con)
このシミュレーションの(一般化された)EMRコールは次のとおりです。
ruby elastic-mapreduce --create --stream --input s3n://bucket/project/input.txt --output s3n://bucket/project/output --mapper s3n://bucket/project/mapper.R --reducer org.apache.hadoop.mapred.lib.IdentityReducer --cache-archive s3n://bucket/project/inputdata.tar.gz#inputdata --name Simulation --num-instances 2
私がこれらの問題を経験しているのかについての洞察がある場合、私は提案とRスクリプトの変更/最適化を受け入れています。
私のもう1つのオプションは、スクリプトを関数に変え、Rマルチコアパッケージを使用して並列化された適用を実行することですが、まだ試していません。これをEMRで機能させたいと思います。使った JDロング と ピート・スコモロック R/EMRは、スクリプトを作成するための基礎としての例です。
解決
明らかなことは何も飛び出しません。ただし、たった10行の単純な入力ファイルを使用してジョブを実行できますか?これらの10行が、大きなテストケースで実行されなかったシナリオであることを確認してください。これを試して、入力がRスクリプトに答えを生成しない可能性を排除します。
EMRジョブのデバッグは、独自のスキルです。
編集:
これは完全な釣り遠征ですが、AWS GUIを使用してEMRインタラクティブピッグセッションを起動します。 「インタラクティブな豚」セッションは維持され、実行されているので、それらをsshすることができます。コマンドラインツールからこれを行うこともできますが、GUIからは少し簡単になります。次に、クラスターにsshを入れて、テストケースに転送して、キャシファイルとマッパーを浸透させてから実行します。
cat infile.txt | yourMapper.R > outfile.txt
これは、マッパーがEMR環境での内陸を邪魔にならないようにすることができるかどうかをテストするためだけです。
編集2:
私は上記のテキストを後世のために残していますが、本当の問題はあなたのスクリプトがより多くのデータを受け取るためにstdinに戻ることは決してないということです。したがって、マッパーごとに1回実行してから終了します。上記の1つのライナーを実行すると、infile.txtの各ラインの結果ではなく、1つの結果しか得られません。実行していた場合 cat
地元のマシンでもテストしてください。エラーが発生するはずです!
それでは、ピートを見てみましょう r例の単語数:
#! /usr/bin/env Rscript
trimWhiteSpace <- function(line) gsub("(^ +)|( +$)", "", line)
splitIntoWords <- function(line) unlist(strsplit(line, "[[:space:]]+"))
## **** could wo with a single readLines or in blocks
con <- file("stdin", open = "r")
while (length(line <- readLines(con, n = 1, warn = FALSE)) > 0) {
line <- trimWhiteSpace(line)
words <- splitIntoWords(line)
## **** can be done as cat(paste(words, "\t1\n", sep=""), sep="")
for (w in words)
cat(w, "\t1\n", sep="")
}
close(con)
スクリプトが欠落している作品はこのビットです:
while (length(line <- readLines(con, n = 1, warn = FALSE)) > 0) {
#do your dance
#do your dance quick
#come on everybody tell me what's the word
#word up
}
当然、カメオの言葉の歌詞を置き換えるべきです!あなたの実際のロジックで。
適切なデバッグ音楽により、プロセスの痛みが軽減されることに注意してください。