私は約15GBのCSVファイルをキャッシュしなければならないSparkアプリケーションを構築しています。私はここスパーク1.6で導入された新しいUnifiedMemoryManager
について読む:Apache Spark:ユーザーメモリとスパークメモリ
https://0x0fff.com/spark-memory-management/
著者は(再びStorage and Execution Memory
に分割されている)User Memory
とSpark Memory
間で異なっています。私が理解しているように、Spark Memoryは実行(シャッフル、並べ替えなど)や保存(キャッシング)に柔軟性があります。もしメモリが必要な場合は、他の部分から使用することができます。この仮定は正しいですか?
ユーザーメモリ:
ユーザメモリは、次のように記述されています。これは、Spark Memoryの割り当て後に残るメモリプールであり、好きなように使用することはあなたの責任です。 RDD変換で使用される独自のデータ構造をそこに格納することができます。たとえば、この集約を実行するmapPartitions変換メンテナンスハッシュテーブルを使用してSpark集約を書き直すことができます。これは、いわゆるユーザーメモリを消費します。 [...]また、これはユーザーメモリーであり、このRAMに格納される内容と方法について完全にあなた自身であり、Sparkはそこで何をしているのか、境界を尊重するかどうかについては全く説明しません。コード内でこの境界を尊重しないと、OOMエラーが発生する可能性があります。
メモリのこの部分にアクセスするにはどうすればよいですか、これはSparkによってどのように管理されますか?
私の目的のために、私はちょうど十分なストレージメモリを持っていなければなりません(シャッフル、ジョインなどのようなことはしません)?では、spark.memory.storageFraction
プロパティを1.0に設定できますか?
私にとって最も重要な質問は、ユーザーメモリはどうですか?それで、それは私の目的のために、私は上で説明しましたか?
いくつかの独自のクラスを使用するようにプログラムを変更すると、メモリの使用に違いがありますか? RDD<String>
の代わりにRDD<MyOwnRepresentationClass>
?ここで
は、ベンチマークアプリケーションでLivy Client
から何度もそれを呼び出して(私のコードスニペットです。私はKryoのシリアライズとスパーク1.6.2を使用しています。
JavaRDD<String> inputRDD = sc.textFile(inputFile);
// Filter out invalid values
JavaRDD<String> cachedRDD = inputRDD.filter(new Function<String, Boolean>() {
@Override
public Boolean call(String row) throws Exception {
String[] parts = row.split(";");
// Some filtering stuff
return hasFailure;
}
}).persist(StorageLevel.MEMORY_ONLY_SER());