DynamicFrameを使った開発をしていたら、大した処理していないのに、想像以上に時間がかかるなと思って調べていたら、JSONの書き出しが時間かかっていました。
タイトルの通り、JSONやCSVでのS3出力と比較してParquetでの出力は凄い早いというお話です。処理全体に影響するくらいの差が出ました。
利用するデータ
AWSから提供されているParquet形式のELBログです。
$ aws s3 ls s3://athena-examples-us-east-1/elb/parquet/year=2015/month=1/ --recursive --summarize --human-readable #--- 省略 2017-02-16 09:43:27 370.4 MiB elb/parquet/year=2015/month=1/day=8/part-r-00157-e764ec48-9e47-4c2c-8d00-68b3a8534cc2.snappy.parquet 2017-02-16 09:43:34 359.4 MiB elb/parquet/year=2015/month=1/day=9/part-r-00013-e764ec48-9e47-4c2c-8d00-68b3a8534cc2.snappy.parquet Total Objects: 31 Total Size: 11.0 GiB
処理内容
何もしないです、上記のデータをカタログ使って読み込んで、そのままS3にパーティション保持して出力しています。
Parquet -> JSON
datasource0 = glueContext.create_dynamic_frame.from_catalog( database = "elbsample", table_name = "elb_parquet", push_down_predicate = "year='2015' and month='01'", transformation_ctx = "datasource0" ) datasink1 = glueContext.write_dynamic_frame.from_options( frame = datasource0, connection_type = "s3", connection_options = { "path": "s3://mybucket/elb/json", "partitionKeys": ['year','month','day'] }, format = "json", transformation_ctx = "datasink1" )
Parquet -> JSON(Gzip)
datasink1 = glueContext.write_dynamic_frame.from_options( frame = datasource0, connection_type = "s3", connection_options = { "path": "s3://mybucket/elb/jsongzip", "compression": "gzip", "partitionKeys": ['year','month','day'] }, format = "json", transformation_ctx = "datasink1" )
Parquet -> CSV(Gzip)
datasink2 = glueContext.write_dynamic_frame.from_options( frame = datasource0, connection_type = "s3", connection_options = { "path": "s3://otomo-glue-test-us-east-1/elb/csvgzip", "compression": "gzip", "partitionKeys": ['year','month','day'] }, format = "csv", transformation_ctx = "datasink2" )
Parquet -> Parquet
datasink1 = glueContext.write_dynamic_frame.from_options( frame = datasource0, connection_type = "s3", connection_options = { "path": "s3://mybucket/elb/parquet", "compression": "gzip", "partitionKeys": ['year','month','day'] }, format = "csv", transformation_ctx = "datasink1" )
他にも
JSON(gzip) -> ParquetやCSV(gzip) -> Parquetなどの変換も比較のため行いました。 上で出力したJSONからParquetへの変換も比較のため行いました。Parquet-> Parquetより時間がかかってました。後は以下の記事見ると読み込みにも差がでるらしいのですが、Parquetの方が遅そうにも見えるし。スキーマの解決が必要だからとかなのかなと想像。でも、それでもJSONやCSVに書き出すよりは圧倒的に早い。
結果
変換 | 出力サイズ | 所要時間 |
---|---|---|
Parquet -> JSON(Gzip) | 16.2GB(93Objs) | 50分 |
Parquet -> JSON | 191.6GB(93Objs) | 49分 |
Parquet -> CSV(Gzip) | 13.3GB(93Objs) | 45分 |
CSV(Gzip)-> JSON(Gzip) | 16.2GB(93Objs) | 53分 |
Parquet-> Parquet | 11.1GB(126Objs) | 14分 |
JSON(Gzip)-> Parquet | 11.1GB(126Objs) | 7分 |
CSV(Gzip)-> Parquet | 11.1GB(126Objs) | 13分 |