私は時間とメモリの両方でSparkの重い数学計算を開発しようとしています(両方ともO(n^2)
まで)。私は、Iterator
を保持しているパーティションは、行ごとに1つのオブジェクトをインスタンス化することを強制しているので、大きな計算にはそれほど適切ではないことが分かっています(遅いですが、Iterator
です)。実際、最も単純なシナリオでは、たとえば、1行に1つのベクトルを保持します。しかし、BLASレベル3までの線形代数演算を改善するパフォーマンスを実際に向上させる可能性があるため、オブジェクトに対するJVMのオーバーヘッドとGCにかかるすべてのプレッシャーを知っているので、メモリにとっては有害です私はこのパラダイムで取り残されているベクトルで行列の代わりに行列)。非常に概略的には、ここで私が達成したいものです。ここでSpark:より良いメモリ管理のためにパーティション・イテレータをブレークしますか?
while (???) { // loop over some condition, doesn't really matter what
val matrix = ??? // an instance of a matrix
val broadMatrix = sparkContext.broadcast(matrix)
// rdd is an instance of RDD[Vector] that is already cached
rdd.mapPartition {
iter =>
val matrixValue = broadMatrix.value()
iter.map (vector => matrixValue * vec)
}
// a bunch of other things relying on that result
}
が私の考えです:
上記のコードでは、私の
rdd
がキャッシュされるように、その後、Iterator
を持つことは無用である、されていませんそれ?唯一の利点は、すべての行を同時にメモリに保持することではないためですが、ここでは計算されキャッシュされているので、すべての行がメモリに保持されます...もちろん、Sparkのインテリジェントなデータをシリアライズして圧縮するキャッシュ(ストレージレベルがMEMORY_ONLY
でも...)もし私が
rdd
に行があるのと同じくらい多くのJVMオブジェクトを持っているので、それが生成する唯一のものは大きなメモリオーバーヘッドですが、パーティションごとに1つのJVMオブジェクト。私は同じエグゼキュータ上にあるすべてのパーティションの共有メモリとして機能するscalaobject
を持つExecutor
という1つのオブジェクトに絞り込むこともできます(これは私がSparkの復元力を維持したいと思うほど難しいかもしれません何らかの理由でパーティションを削除し、別のエグゼキュータに再表示する必要がある場合は、自分で処理するのではなく、関連するすべてのオブジェクトを単独で移動させます...)。
私の考え故に何かのように、行列を含んだものにvector
のこのrdd
を変換するために、次のようになります。
while (???) { // loop over some condition, doesn't really matter what
val matrix = ??? // an instance of a matrix
val broadMatrix = sparkContext.broadcast(matrix)
// rdd is an instance of RDD[Vector] that is already cached
rdd.mapPartition {
iter =>
val matrixValue = broadMatrix.value()
// iter actually contains one single element which is the matrix containing all vectors stacked
// here we have a BLAS-3 operation
iter.map (matrix => matrixValue * matrix)
}
// a bunch of other things relying on that result
}
すでにこのジレンマに直面して誰ですか?あなたはこれと同じようにメモリ管理の事前使用を経験しましたか?
Iteratorをnon-lazy collectionに変更すると、rddがキャッシュされていてもsparkが再びメモリを消費することが想像できます(2回)。私はあなたがちょうどいくつかのベンチマークを使用してより良いバージョンを試してみるべきだと思う –
私はスパークが実際にメモリを2回消費すると想像し...私はそれを試して、私はより良いパフォーマンスがあるかどうかを見ていきます。私はベンチマークの結果をすぐに私はそれらを持って与えるでしょう! –