こんにちは!データ周りをやってる朴です。
先日ご紹介があったとおり「開発・デザイン部」はついに独立?!して違うフロアに移動しました。
つい先日まで冷蔵庫も電子レンジもなく少し寂しい感じがしたのですが、本日ついに必需品が揃い、
みんながテンション上々↑↑です。
そして冷蔵庫にはチームメンバーの福田さんが自腹でガリガリ君をフル補充!何という太っ腹!
いつもありがとうございます!
で!今日は先日リリースされたApache Spark 2.3 でORCのファイルの読み込みが性能向上した内容が
含まれていたので、それについて検証してみたいと思います。
該当リリースはSPARK-16060
以下本文引用
Adds support for new ORC reader that substantially improves the ORC scan throughput through vectorization (2-5x). To enable the reader, users can set spark.sql.orc.impl to native.
これに関連したリリースとしてApache ORC 1.4.0がサポートされるようになり、
Apache Spark2.3からはHive ORCとApache ORC2種類のORCデータフォーマットが読み書きできるようになりました。
検証内容
ORCデータフォーマット 2種類(Hive ORC, Apache ORC) と readerの2種類(hive, native=Vectorized ORC Reader)でそれぞれ4パターンの確認を行います。
テストデータ
日本国特許公報の書誌データ(特許の概要と出願日などの情報)約100万件(snappy圧縮したparquetフォーマットで容量は約775 MB)
上記のテストデータをそれぞれHive ORCフォーマットとApache ORCフォーマットで保存します。
- Apache ORCフォーマットで保存する
scala> val _research = spark.read.parquet("/user/s.paku/gazette_data_parquet/published_research/*") scala> _research.write.format("org.apache.spark.sql.execution.datasources.orc").save("/user/s.paku/gazette_data_orc/research_native")
Apache ORCフォーマットで保存するにはwrite.format("org.apache.spark.sql.execution.datasources.orc")指定するか、
spark.conf.set("spark.sql.orc.impl","native")にしてdf.write.orc(path)で保存できます。
- Hive ORCフォーマットで保存する
scala> val _research = spark.read.parquet("/user/s.paku/gazette_data_parquet/published_research/*") scala> _research.write.format("orc").save("/user/s.paku/gazette_data_orc/research_hive")
SparkSQLのORCがHiveの状態で Hive ORC フォーマットと Apache ORCフォーマットの読み込み性能検証
※Spark 2.3までのデフォルトのORC はhiveとなります
- hiveフォーマットをhive readerで読み込む
scala> spark.conf.get("spark.sql.orc.impl") res0: String = hive scala> spark.time(spark.read.orc("/user/s.paku/gazette_data_orc/research_hive").count) Time taken: 21662ms res0: Long = 1121565
- Apache ORCフォーマットをhive readerで読み込む
scala> spark.conf.get("spark.sql.orc.impl") res0: String = hive scala> spark.time(spark.read.orc("/user/s.paku/gazette_data_orc/research_native").count) Time taken: 20698 ms res1: Long = 1121565
上記の結果からはSpark sqlのORC設定がhiveの場合、新旧ORCフォーマットでパフォーマンス的にそんなに変わらないことが分かります。
SparkSQLのORCがnativeの状態で Hive ORC フォーマットと Apache ORCフォーマットの読み込み性能検証
spark.conf.set("spark.sql.orc.impl","native") scala> spark.conf.get("spark.sql.orc.impl") res2: String = native scala> spark.time(spark.read.orc("/user/s.paku/gazette_data_orc/research_native").count) Time taken: 16773 ms res0: Long = 1121565
scala> spark.conf.get("spark.sql.orc.impl") res0: String = native scala> spark.time(spark.read.orc("/user/s.paku/gazette_data_orc/research_hive").count) 18/05/29 12:19:43 WARN util.Utils: Truncated the string representation of a plan since it was too large. This behavior can be adjusted by setting 'spark.debug.maxToStringFields' in SparkEnv.conf. Time taken: 18544 ms res1: Long = 1121565
Spark SQLのORCをnativeに設定した、結果新旧orcフォーマットでいずれも高い性能が出てます。
上記結果表にまとめると
orc reader | data format | count time (ms) |
---|---|---|
native | Apache ORC | 16773 |
native | Hive ORC | 18544 |
hive | Apache ORC | 20698 |
hive | Hive ORC | 21662 |
リリースドキュメントとおりの性能は出てないものの新ORCフォーマットでspark.sql.orc.implをnativeに設定したときに最も性能が発揮されてることが分かります。
データ量とデータサイズによって性能の差は広がるかも知れません。
その辺SparkとORCの歴史と取り組みを良く纏めた資料がこちらORC improvement in Apache Spark 2.3にあります。
ちなみに上記同様のデータをparquetで読み込むと12649 msという結果でparquetの読み込み性能が最優位である結果となりました。
最後に
いつものことですが、SparkとかHadoopとかMongoとかElasticSearchとかゴリゴリいじる仲間を募集してますので、ご応募お待ちしております。