フューチャー技術ブログ

5TB/日 のデータをAWS Glueでさばくためにやったこと(性能編)

フューチャー Advent Calendar 2018 Qiita 5日目の記事です。

みなさん、こんにちは。
本記事は、AWS Glueについてのサービス概要や開発Tipsを紹介する5TB/日 のデータをAWS Glueでさばくためにやったこと(概要編)の続編で、Glueの性能検証した内容を共有していきます。

検証について

Glueの性能がテーマですが、Glueそのものには設定できるパラメータが少ないためチューニングの余地が比較的小さいです。

その中で、Glueの機能に着目すると以下の1~4が挙げられると思います。

  1. DPU数
    • ジョブに使用されるDPU(Data Processing Unit)の数、Sparkで言うところのworker nodeの数に該当
    • 1DPUは4vCPU、16GBのメモリを持ち、これ以外を選択することは不可
    • ジョブ実行に使用できるDPU数は最低2つ、最大で100まで設定可能
  2. データカタログの使用有無
    • Glueは、クローリングによりデータカタログというメタデータを自動生成できる
    • データを読み込む際は、このデータカタログを利用することも、利用しないこともできる
  3. ファイル形式
    • Glueではデータの入出力にGlueContextを使用します
    • 様々な形式のファイルに対応していますが、ファイルの形式別にリードライトに性能差がある
    • 以下のファイルフォーマットは入力・出力の両方に対応
      • avro
      • csv
      • json
      • orc
      • parquet
    • 以下のファイルフォーマットは入力のみに対応
      • ion
      • grokLog
      • xml
  4. ファイルパーティション
    • GlueContextを使用してS3へファイルを出力する際に、特定の項目でパーティション分割することが可能
    • これにより読み込む際に必要なファイルのみを読み込むことが可能

今回は、「1.DPU」を除いた、2~4を検証していきます。

※Glueの内部で利用されているSparkそのものの性能についてはスコープ外としてますのでご了承ください。

検証用データ

検証用ダミーデータには以下のものを使用しました。

  • 件数 : 2000万レコード
  • カラム数 : 4パターンの連番を持つ4カラム
  • データ : 1 ~ 1000000までの値

データイメージ

No column1 column2 column3 column4
1 1 1 1 1
2 1 1 1 1
19 1 1 1 1
20 1 1 1 1
21 2 1 1 1
22 2 1 1 1
1999 100 1 1 1
2000 100 1 1 1
2001 101 2 1 1
2002 101 2 1 1
199999 10000 100 1 1
200000 10000 100 1 1
200001 10001 101 2 1
200002 10001 101 2 1
19999999 1000000 10000 100 1
20000000 1000000 10000 100 1

またデータの形式は以下のものを用意しました。

拡張子 ファイルサイズ 備考
csv 334.0MB
avro 414.1MB
json.gz 58.5MB jsonをgzipで圧縮。Glueで対応しており、未解凍で読み込み可能
json 1.65GB
snappy.orc 83.5MB 圧縮方式にsnappyを選択したorcバイナリファイル
snappy.parquet 86.8MB 圧縮方式にsnappyを選択したparquetバイナリファイル

Glueは数百GB、数億カラムレベルのデータサイズも対応可能ですが、今回はこのデータで検証を行います。(データを作るのが大変だったため…)

検証結果

先に説明したダミーデータを用いて検証します。
環境はGlue、S3ともに東京リージョンを利用しています。特に明記しない場合は、ファイル形式はCSVを利用し、検証結果は10回計測した平均値を記載しています。

検証(1) DPU数

DPU数を増やすと時間がかかるタスクも高速化が期待できますが、今回の検証からは割愛します。

検証(2) データカタログの使用有無

データカタログの利用する、しないで検証しました。
しないケースはさらに、2種類のAPIで比較して検証しました。

  • 検証結果
方式 読み込み時間[s]
データカタログ利用 0.3019
GlueContextのfrom_option利用 0.2461
Sparkのread.csvを利用 0.7811
  • コメント
    • 結果にあまり差が出なかったため、実装方式に合わせて任意のものを選択するで良いと思います

検証(3) ファイル形式

パーティションを切らず、いくつかのファイル形式でS3から読込/書出 を行い検証しました。

  • 読込結果
拡張子 読み込み時間[s]
csv 0.1305
avro 0.1144
json.gz 0.1211
json 0.3420
snappy.orc 0.4451
snappy.parquet 0.3794
  • 書出結果
拡張子 書き出し時間[s]
csv 6.9508
avro 12.8020
json 15.1127
snappy.orc 13.9531
snappy.parquet 11.6287
  • コメント
    • 読込に関してはほとんど差が見受けられませんでした。10回実施した際の各回にもばらつきがあるため、誤差の範囲内かと思われます
    • 書出には明確な差が出ました
      • 特にjsonは遅く、変換に時間がかかったものと推測
      • CSVが一番早いですが、ファイルサイズが大きくなってしまうのがネック
    • 性能やファイルサイズを考えると、avroやparquetといった、バイナリファイルの選択が有力ではないでしょうか
      • 今回のわたしの在籍していたPJではparquetを採用しました
      • バイナリファイルは、内容の確認やデータ作成に一手間かかるため、開発時にはCSVを使い、テストや本運用の時のみparquetを利用するという手法が良いかと思います

検証(4) ファイルパーティション

パーティション数を変化させてS3から読込/書出 を実施しました。

  • 読込結果(5回計測、その平均値)
拡張子 読み込み時間[s]
1 0.0793
100 0.1565
10000 0.1986
  • 書出結果(5回計測、その平均値)
拡張子 書き出し時間[s]
1 70.1816
100 58.3604
10000 410.1765
1000000 6時間待っても終了しなかったので中断
  • コメント
    • 読込はあまり差が出ませんでした(実は読み込まれていないのでは? と不安に思い、別の手段でも確かめましたが同じ結果でした)
    • 書出はパーティション数を増やした場合に著しく性能が落ちました
    • 開発時は細かくパーティションを切った方が目的のファイルにたどり着きやすく、デバッグしやすかったです
    • パーティション設計はGlue利用時の肝ですが、実アプリへ適用したパーティション設計は、後続処理の内容やサービスに依存するため一言では言い難いです
      • 例1: 後続がGlueの場合、時間課金ですので出力時にはパーティションは大きくは切らず、短時間で出力し切った方がコストを削減できます。
      • 例2: 後続がAthenaの場合、読み取ったデータサイズに対して課金されますのでパーティションを細かく切り、余計なデータは読まないようにした方がコストは削減できます

その他

ここまで処理時間について検証しましたが、見逃しやすくもネックになりやすいのはGlueのクラスタ構築にかかる時間です。

Glue jobを実行する場合は、必ずクラスタの構築が開始されますが、このクラスタ構築が曲者で、構築に必要なDPUの確保に数分の時間がかかる場合があります。

もちろんjobが数時間レベルのものであれば、数分間は誤差かもしれません。

しかし最悪の場合、時間がかかるだけでなくそもそもDPUの確保に失敗し、job自体が動かないという事象が発生します。

クラスタ構築時間、job失敗率は要求するDPUの数に応じて大きくなります。DPU確保失敗時には設定回数を上限としたリトライも可能ですが、それでも100%実行できるという保証はありません。

残念ながらGlueにはリザーブドの考え方は存在しないため、DPU確保に関する問題を回避する方法は現在のところ存在しません。

2018年11月時点での東京リージョンで触ってみた感覚では、以下のような感じです。

  • 10(デフォルト):クラスタ構築に5~10分前後ほどかかる。DPU確保失敗はほぼ起こらない
  • 20:クラスタ構築に15分ほどかかる。DPU確保失敗する割合は五分五分程度
  • 30:DPU確保にほぼ失敗する

ただし実行する時間帯も関係するようで、朝5時など利用者が少ないような時間だとDPUの確保できる成功率が高くなるようです。

まとめ

  • データの読込は、ファイルの形式やパーティションの切り方に関わらず高速
  • データの書出は、parquetなどの圧縮形式が高速で、サイズも小さい。またパーティション数が多いほど時間がかかる
  • ミニサイズのジョブにおいて、性能面で最も考慮すべきはGlueのDPU確保の不安定さ。DPU確保にかかる時間は要注意。最悪、確保できずに実行失敗する。今後のサービスの成熟に期待

あとがき

いかがだったでしょうか? 性能編と言っておきながら最後はサービスとしてまだ発展途上という終わり方になってしまいましたが、AWSのサービスの成熟スピードはとても早いため、きっと近い将来に改善されているのではと思います。

実際、Glueを日々使っている中で新しい機能がどんどん追加されていき、便利に使いやすくなっていきました。

開発をしながら機能追加に驚き、裏の改善を行なっているであろうAWSのエンジニアさんのことを想い、一緒に仕事ができているようで尊敬やら激励やらの念を抱いていた当時のことを、記事を書きながら思い出しました。

私も彼らに負けないよう、のっぴきならない人生を乗り越えていくために、さらに切磋琢磨していきたいと想います。