私はjava-sizeof
ライブラリ(https://github.com/phatak-dev/java-sizeof)で遊んでいて、Apache Sparkでデータセットのサイズを測定しています。それが判明したので、オブジェクトはばかげて大きいです。大規模なように - それはなぜですか?Spark Rowオブジェクトが同等の構造体に比べて大きすぎるのはなぜですか?
はかなり単純なスキーマを取る:
root
|-- account: string (nullable = true)
|-- date: long (nullable = true)
|-- dialed: string (nullable = true)
|-- duration: double (nullable = true)
例のデータは、次のようになります。
+-------+-------------+----------+--------+
|account| date| dialed|duration|
+-------+-------------+----------+--------+
| 5497|1434620384003|9075112643| 790.0|
+-------+-------------+----------+--------+
は、だから今、私たちは行います
val row = df.take(1)(0)
// row: org.apache.spark.sql.Row = [5497,1434620384003,9075112643,790.0]
は、だから今はSizeEstimator
SizeEstimator.estimate(row)
// res19: Long = 85050896
81メガバイト!単一の行の場合!これは間違いのいくつかの種類がされて考えて、私が行います
SizeEstimator.estimate(df.take(100))
// res20: Long = 85072696
興味深いことに、それははるかに大きいではありません - 100倍のデータ量を保持しているにもかかわらず、たったの約20Kより大きく。 100を超えると線形になるようです。 1,000行の場合、次のようになります。
SizeEstimator.estimate(df.take(1000))
// res21: Long = 850711696
[OK]を選択すると、100行より約10倍大きくなります。テストからは、100行を超えて直線的に増加します。これらのテストに基づいて、約100行後、Rowオブジェクトあたりのコストはまだ800 KBを超えています !!
好奇心を持たずに、私は同じ根底にあるデータに対して2種類のオブジェクトタイプを試しました。例えば、ここでArray
Array
のオブジェクトの結果の代わりに、オブジェクトです:
SizeEstimator.estimate(
df.map(r => (r.getString(0), r.getLong(1), r.getString(2), r.getDouble(3))).take(1)
)
// res22: Long = 216
は、[OK]を、それは少しはましです。さらに良いのは、10行の場合は1976バイトのみであり、100の場合は19,616バイトであることです。確かに正しい方向に行く。
そして、Iは、基礎となるDataFrame
と同じスキーマで、各Array[Byte]
バイナリエンコードAvro
レコードであるRDD[Array[Byte]]
同じDataFrame
をコードしていました。それから、私はこうします:
SizeEstimator.estimate(encodedRdd.take(1))
// res23: Long = 72
72バイト - さらに良い!そして、100行の場合、それは5,216バイトであり、行は約52バイトであり、そこから降り続ける(1,000レコードの場合、48,656バイト)。それは最高の状態で同じデータのバイナリAvro
記録は約50バイトであるのに対し
ので、オブジェクトは、あたり850Kの重さ。
何が起こっていますか?
ではありません。これは推移的なオブジェクトグラフのバイト数を評価しています。これは、Rowオブジェクト自体がメモリやディスクにどれだけの記憶域を取っているかとはまったく関係ありません。パーティションブーキングなどで、おそらく巨大なキャッシュデータ構造を数えているでしょう。 –
@SeanOwenここでは奇妙なことが起きています。それは 'StructField'のすべてであるようです。 [最小限の例で要点を作成しました](https://gist.github.com/zero323/0a8ef3636a6c4414d1bfcb9e6bfef94c)(コンテキストなし、 'DataFrames'、単一' StructField')、それでも不条理な数字が出ます(271872172) 。 – zero323
私はこの方法であなたが期待している数字を与えることはないと思います。 Rowオブジェクトとデータフィールドだけで消費されるメモリの量をどうにかしようとするわけではありません。それは推移的オブジェクトグラフ全体のどれがどれほど大きなものかを示しています。そのほとんどは行データではありません。 –