web-dev-qa-db-ja.com

SparkのキーでRDDを分割する方法は?

HashPartitionerのドキュメントが言うことを考えると:

[HashPartitioner]は、JavaのObject.hashCodeを使用してハッシュベースのパーティショニングを実装します。

DeviceDataをそのkindで分割したいとします。

_case class DeviceData(kind: String, time: Long, data: String)
_

deviceData.hashCode()メソッドを上書きして_RDD[DeviceData]_を分割し、kindのハッシュコードのみを使用することは正しいでしょうか?

しかし、HashPartitionerがいくつかのパーティションパラメーターを受け取ることを考えると、種類の数を事前に知る必要があるかどうかと、パーティションよりも種類が多い場合はどうなるかについて混乱しますか?

パーティション化されたデータをディスクに書き込んだ場合、読み取り時にパーティション化されたままになるのは正しいことですか?

私の目標は電話することです

_  deviceDataRdd.foreachPartition(d: Iterator[DeviceData] => ...)
_

また、イテレータには同じDeviceData値のkindのみを含めます。

11
BAR

groupByKeyを使用してkindを実行するのはどうですか。または別のPairRDDFunctionsメソッド。

あなたはパーティション分割について本当に気にしていないように見えますが、1つの処理フローで特定の種類のすべてを取得しているだけですか?

ペア関数はこれを可能にします:

rdd.keyBy(_.kind).partitionBy(new HashPartitioner(PARTITIONS))
   .foreachPartition(...)

ただし、次のようなものを使用すると、おそらく少し安全になります。

rdd.keyBy(_.kind).reduceByKey(....)

またはmapValuesまたは、全体としてピースを取得することを保証する他のいくつかのペア関数

9
Justin Pihony

DeviceData.hashCode()メソッドを上書きしてRDD [DeviceData]を分割し、種類のハッシュコードのみを使用することは正しいでしょうか?

そうではありません。 Java _Object.hashCode_のドキュメントを参照すると、hashCodeの一般契約に関する次の情報が見つかります。

Equals(Object)メソッドに従って2つのオブジェクトが等しい場合、2つのオブジェクトのそれぞれでhashCodeメソッドを呼び出すと、同じ整数の結果が生成される必要があります。

したがって、純粋にkindのデバイスに基づく等式の概念がユースケースに適合しない限り、私がそれを真剣に疑っていない限り、HashCodeをいじって目的のパーティション分割を取得することは悪い考えです。一般的には 独自のパーティショナーを実装する が必要ですが、ここでは必要ありません。

SQLとGraphXの特殊なシナリオを除いて、partitionByPairRDDでのみ有効であるため、RDD[(String, DeviceData)]を作成してプレーンHashPartitionerを使用することは理にかなっています

_deviceDataRdd.map(dev => (dev.kind, dev)).partitionBy(new HashPartitioner(n))
_

kindのカーディナリティが低い場合や、分配にそれを使用して分布が大きく歪んでいる場合は、最適なソリューションではない可能性があることに注意してください。

9
zero323