ほとんどの場合hiveContext.sql()
を起動する次のコードがあります。私のタスクは、いくつかのテーブルを作成し、すべてのHiveテーブルパーティションの処理後に値を挿入することです。
そのため、最初にshow partitions
を起動し、その出力をforループで使用して、テーブルを作成し(存在しない場合)、hiveContext.sql
を使用してそれらに挿入するいくつかのメソッドを呼び出します。
今、エグゼキューターでhiveContext
を実行できないため、これをドライバープログラムのforループで実行する必要があり、逐次実行する必要があります。これを送信すると、Spark YARNクラスターのジョブ)、シャッフルが見つからないという例外のために、ほとんどの場合、エグゼキューターが失われます。
これは、メモリの過負荷のためにYARNがエグゼキュータを殺しているために発生しています。各Hiveパーティションに非常に小さいデータセットがあるため、理由はわかりませんが、それでもYARNがエグゼキュータを強制終了します。
次のコードはすべてを並行して実行し、すべてのHiveパーティションデータを同時にメモリに収容しようとしますか?
public static void main(String[] args) throws IOException {
SparkConf conf = new SparkConf();
SparkContext sc = new SparkContext(conf);
HiveContext hc = new HiveContext(sc);
DataFrame partitionFrame = hiveContext.sql(" show partitions dbdata partition(date="2015-08-05")");
Row[] rowArr = partitionFrame.collect();
for(Row row : rowArr) {
String[] splitArr = row.getString(0).split("/");
String server = splitArr[0].split("=")[1];
String date = splitArr[1].split("=")[1];
String csvPath = "hdfs:///user/db/ext/"+server+".csv";
if(fs.exists(new Path(csvPath))) {
hiveContext.sql("ADD FILE " + csvPath);
}
createInsertIntoTableABC(hc,entity, date);
createInsertIntoTableDEF(hc,entity, date);
createInsertIntoTableGHI(hc,entity,date);
createInsertIntoTableJKL(hc,entity, date);
createInsertIntoTableMNO(hc,entity,date);
}
}
通常、実際の例外を取り除くには、常にログを掘り下げる必要があります(少なくともSpark 1.3.1)。
tl; dr
Spark for Yarnの下での安全な設定spark.shuffle.memoryFraction=0.5
-これにより、割り当てられたメモリをシャッフルで使用できるようになりますspark.yarn.executor.memoryOverhead=1024
-これはMBで設定されます。ヤーンは、メモリ使用量が(executor-memory + executor.memoryOverhead)よりも大きい場合、エグゼキュータを強制終了します
少し詳しい情報
あなたはあなたの質問を読んで、あなたはあなたがシャッフルが見つかりません例外を得ると述べました。
の場合には org.Apache.spark.shuffle.MetadataFetchFailedException: Missing an output location for shuffle
増やす必要がありますspark.shuffle.memoryFraction
、例えば0.5
ヤーンが私のエグゼキュターを殺害した最も一般的な理由は、予想以上のメモリ使用量でした。それを避けるには、spark.yarn.executor.memoryOverhead
、実行者が2〜3Gのメモリしか使用しない場合でも、1024に設定しました。
これは私の仮定です。クラスターで実行者が制限されている必要があり、ジョブが共有環境で実行されている可能性があります。
あなたが言ったように、あなたのファイルサイズは小さいです、より少ない数のエグゼキューターを設定し、エグゼキューターコアを増やすことができ、memoryOverhead
プロパティの設定はここで重要です。
上記のプロパティを使用すると、パフォーマンスを犠牲にすることなく、エグゼキュータのメモリ不足の問題を回避できると確信しています。