================================================================= AWS Glue + Iceberg で電力データを取り込み、処理時間を計測してみた ================================================================= .. list-table:: :widths: 20 80 * - 公開日 - 2026-01-29 * - 掲載 - ENECHANGE Developer Blog * - 出典 - https://tech.enechange.co.jp/entry/2026/01/29/131005 はじめに -------- 以下の記事で、AWS Glue と Iceberg を用いて分析基盤を作成してみました。 本記事では、この分析基盤に対して 1万〜15万件 のデータを取り込み、以下の観点で検証します。 - Glue Job の処理時間(XML パース → Iceberg MERGE)の計測 - データ量に対する処理時間のスケーリング傾向の把握 - ワーカー数(並列度)による効果の確認 `tech.enechange.co.jp `__ .. _電力使用量データ量-と-AWS-Glue-ワーカー数: 電力使用量データ量 と AWS Glue ワーカー数 ----------------------------------------- .. _1-電力使用量データ量ファイル数: 1. 電力使用量データ量(ファイル数) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - 1日分の需要家数を1万件、2万件、5万件、10万件、15万件と変動させます。 - 1ファイル = 1万需要家(重複なし)分の 1日の電力使用量を保存しています。 ========== ======== ファイル数 需要家数 ========== ======== 1 1万 2 2万 5 5万 10 10万 15 15万 ========== ======== .. _2-Glue-ワーカー数: 2. Glue ワーカー数 ~~~~~~~~~~~~~~~~~~ Glueのワーカータイプ と バージョンを以下のように設定して、3回ずつ処理時間を計測していきます。 - Glue ワーカータイプ : G.1X(4 vCPU , 16GB RAM ) - Glue バージョン : 5.0 ========== ========== ワーカー数 DPU (G.1X) ========== ========== 2 2 5 5 10 10 ========== ========== テストケース ------------ - 上記の電力使用量データ量とAWS Glue ワーカー数のパターンを組み合わせると15個のテストケースができます。 - 1テストケースごとに、3回ずつ処理時間を計測していきます。 == ======== ========== ========== # 需要家数 ファイル数 ワーカー数 == ======== ========== ========== 1 1万 1 2 2 1万 1 5 3 1万 1 10 4 2万 2 2 5 2万 2 5 6 2万 2 10 7 5万 5 2 8 5万 5 5 9 5万 5 10 10 10万 10 2 11 10万 10 5 12 10万 10 10 13 15万 15 2 14 15万 15 5 15 15万 15 10 == ======== ========== ========== 処理時間の取得方法 ------------------ - AWS Glue コンソールで実行時間を確認 - または AWS CLI で取得: .. code:: bash aws glue get-job-runs --job-name consumption-xml-to-iceberg --max-results 10 検証手順 -------- .. _1-サンプルデータ生成: 1. サンプルデータ生成 ~~~~~~~~~~~~~~~~~~~~~ - 以下の構造で、1万件分の電力使用量データを含むXMLファイルを生成します。 .. code:: xml CUST-001234 2024-01-15 2024-01-16T06:30:00+09:00 1.2 1.1 1.3 CUST-001235 2024-01-15 2024-01-16T06:30:00+09:00 1.2 1.1 1.3 .. _2-テスト実行: 2. テスト実行 ~~~~~~~~~~~~~ テストは以下の手順で進めます。 - S3 へアップロード - Iceberg テーブルのクリーンアップ - Glue Job 実行(ワーカー数を指定) - 処理時間の計測 .. _3-結果記録: 3. 結果記録 ~~~~~~~~~~~ 処理時間を記録し、結果記録テーブルを更新します。 手順1〜3を各テストケースで繰り返します。 結果記録 -------- == ======== ========== ===== ===== ===== ==== # 需要家数 ワーカー数 1回目 2回目 3回目 平均 == ======== ========== ===== ===== ===== ==== 1 1万 2 122s 63s 65s 83s 2 1万 5 126s 138s 133s 132s 3 1万 10 133s 169s 176s 159s 4 2万 2 148s 140s 137s 142s 5 2万 5 132s 141s 130s 134s 6 2万 10 123s 137s 184s 148s 7 5万 2 190s 188s 191s 190s 8 5万 5 158s 156s 162s 159s 9 5万 10 149s 201s 154s 168s 10 10万 2 533s 544s 548s 542s 11 10万 5 260s 261s 268s 263s 12 10万 10 267s 269s 232s 256s 13 15万 2 753s 777s 749s 760s 14 15万 5 280s 325s 283s 296s 15 15万 10 259s 220s 225s 235s == ======== ========== ===== ===== ===== ==== 結果サマリー ------------ - 需要家数が増えるほど処理時間が増加しますが、ワーカー数を増やすことで処理時間を短縮できます。特に10万件以上ではワーカー2と、ワーカー5・10の差が顕著になります。 - 以下のグラフは、需要家数の増加に伴う処理時間の変化を可視化したものです。 .. image:: images/enechange-2026-01-29-glue-iceberg-benchmark/20260129131006.png ======== ========== ========= ========= ========== ========== 需要家数 ファイル数 ワーカー2 ワーカー5 ワーカー10 最速 ======== ========== ========= ========= ========== ========== 1万 1 **83s** 132s 159s ワーカー2 2万 2 142s **134s** 148s ワーカー5 5万 5 190s **159s** 168s ワーカー5 10万 10 542s 263s **256s** ワーカー10 15万 15 760s 296s **235s** ワーカー10 ======== ========== ========= ========= ========== ========== 考察 ---- ファイル数とワーカー数の関係 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - ファイル数 < ワーカー数 → 効果が出にくい - ファイル数 ≥ ワーカー数 → 並列処理の効果が発揮される 推奨設定(ファイル分割あり前提) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ========== ============== データ規模 推奨ワーカー数 ========== ============== 〜2万件 2 2〜5万件 5 10万件以上 10 ========== ============== -------------- 追加検証: ファイル分割 vs 1ファイル ----------------------------------- 検証目的 ~~~~~~~~ 同じ需要家数でファイル数を変えた場合の処理時間を比較し、処理時間にどのような差が出るか観察する。 .. _テストケース-1: テストケース ~~~~~~~~~~~~ == ======== ========== ========== # 需要家数 ファイル数 ワーカー数 == ======== ========== ========== 1 2万 1 2 2 2万 1 5 3 2万 1 10 4 5万 1 2 5 5万 1 5 6 5万 1 10 7 10万 1 2 8 10万 1 5 9 10万 1 10 10 15万 1 2 11 15万 1 5 12 15万 1 10 == ======== ========== ========== .. _結果記録-1: 結果記録 ~~~~~~~~ == ======== ========== ========== ===== ===== ===== ==== # 需要家数 ファイル数 ワーカー数 1回目 2回目 3回目 平均 == ======== ========== ========== ===== ===== ===== ==== 1 2万 1 2 163s 164s 215s 181s 2 2万 1 5 156s 234s 145s 178s 3 2万 1 10 205s 153s 158s 172s 4 5万 1 2 312s 223s 274s 270s 5 5万 1 5 231s 221s 208s 220s 6 5万 1 10 209s 211s 234s 218s 7 10万 1 2 365s 353s 376s 365s 8 10万 1 5 320s 319s 317s 319s 9 10万 1 10 312s 319s 356s 329s 10 15万 1 2 502s 454s 468s 475s 11 15万 1 5 419s 427s 450s 432s 12 15万 1 10 448s 428s 440s 439s == ======== ========== ========== ===== ===== ===== ==== 比較結果 ~~~~~~~~ - ファイル分割ありの場合、ワーカー5・10で処理時間が大きく短縮されています。一方、1ファイルの場合はワーカー数を増やしても処理時間の改善が限定的になります。 - 以下のグラフは、同じ需要家数での「ファイル分割あり」と「1ファイル」の処理時間を比較したものです。 - 青がファイル分割、赤が1ファイル です。 .. image:: images/enechange-2026-01-29-glue-iceberg-benchmark/20260129131009.png ======== ========== ========= ========= ========== ========== 需要家数 ファイル数 ワーカー2 ワーカー5 ワーカー10 最速 ======== ========== ========= ========= ========== ========== 2万 1 181s 178s **172s** ワーカー10 2万 2 142s **134s** 148s ワーカー5 5万 1 270s 220s **218s** ワーカー10 5万 5 190s **159s** 168s ワーカー5 10万 1 365s **319s** 329s ワーカー5 10万 10 542s 263s **256s** ワーカー10 15万 1 475s **432s** 439s ワーカー5 15万 15 760s 296s **235s** ワーカー10 ======== ========== ========= ========= ========== ========== 追加検証のまとめ ~~~~~~~~~~~~~~~~ **発見事項** - **ワーカー2**: 10万件以上で1ファイルの方が速い - **ワーカー5**: 全データサイズでファイル分割が優位 - **ワーカー10**: 大規模データでファイル分割の効果が顕著 **推奨設定(総合判断)** +-------------------------------------+----------------+----------------------------+ | 条件 | 推奨ワーカー数 | 理由 | +=====================================+================+============================+ | 通常運用(ファイル分割あり) | 5 | コストと速度のバランス最良 | +-------------------------------------+----------------+----------------------------+ | 大量データ急ぎ(10万件+、分割あり) | 10 | 並列効果最大 | +-------------------------------------+----------------+----------------------------+ | 1ファイルのみ | 5 | 10にしても速度向上しない | +-------------------------------------+----------------+----------------------------+ .. _Spark-UI-分析: Spark UI 分析 ------------- .. _Stage-比較-1ファイル-vs-15ファイル分割: Stage 比較: 1ファイル vs 15ファイル分割 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. _1ファイル-総処理時間-440s: 1ファイル (総処理時間: 440s) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ===== ========== ======== ======================= Stage 時間 タスク数 処理内容 ===== ========== ======== ======================= 0 **316.0s** **1** XMLパース (repartition) 1 6.9s 20 count 3 3.6s 20 DynamicFrame変換 6 7.2s 20 SQL処理 7 10.8s 20 SQL処理 10 1.8s 36 SQL処理 14 4.4s 1 MERGE書き込み ===== ========== ======== ======================= .. _15ファイル分割-総処理時間-259s: 15ファイル分割 (総処理時間: 259s) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ===== ========= ======== ================= Stage 時間 タスク数 処理内容 ===== ========= ======== ================= 0 **52.6s** **15** XMLパース (count) 1 32.2s 15 DynamicFrame変換 3 53.4s 15 SQL処理 4 56.3s 15 SQL処理 6 2.2s 36 SQL処理 9 4.2s 1 MERGE書き込み ===== ========= ======== ================= 分析結果 ~~~~~~~~ ================= ========= ========== =========== 項目 1ファイル 15ファイル 改善率 ================= ========= ========== =========== XMLパース時間 316s 53s **6倍高速** XMLパースタスク数 1 15 15並列化 総処理時間 440s 259s 41%短縮 ================= ========= ========== =========== ボトルネックの特定 ~~~~~~~~~~~~~~~~~~ #. **1ファイルの場合**: Stage 0 (XMLパース) が316秒で全体の72%を占める。タスク数が1のため、ワーカーを増やしても並列化できない。 #. **15ファイル分割の場合**: Stage 0 が15タスクで並列実行され、52.6秒に短縮。各ワーカーが独立してファイルを処理できる。 #. **根本原因**: ``glueContext.create_dynamic_frame.from_options`` でのXMLパースは、ファイル単位でしか並列化されない。1ファイル内のレコードは順次処理される。 参考: タスク分散の仕組み ~~~~~~~~~~~~~~~~~~~~~~~~ - G.1X ワーカー = 4 vCPU = 4 cores (4並列スロット) - 10ワーカー = 1 Driver + 9 Executor = 36並列スロット - 15ファイル → 15タスク → 4 Executor × 4 cores で同時実行 結論 ---- - **ファイル分割が最重要**: ワーカー数を増やすより、ファイル分割の方が効果大 - **ワーカー数はファイル数に合わせる**: ワーカー数 ≤ ファイル数 が基本(余剰ワーカーは効果が出にくい) - **ワーカー5が汎用的**: ほとんどのケースで最適またはそれに近い性能 - **ワーカー10は条件付き**: 10ファイル以上 × 10万件以上の場合のみ有効 本番運用に向けて ---------------- 今回の検証はワーカー数(2/5/10)とファイル数(1〜15)の限られた範囲で実施しました。本番環境では、実際のデータ量・ファイル数・処理時間の要件に応じて、ワーカー数やワーカータイプのチューニングが必要です。 特に以下の点を考慮してください: - **コストと速度のトレードオフ**: ワーカー数やワーカータイプを上げれば速くなるがDPUコストも増加 - **ファイル数との関係**: ファイル数以上にワーカーを増やしても効果は限定的 - **SLA要件**: 処理時間の制約がある場合は、それに合わせた設定が必要 今後の課題 ---------- 今回はSpark UIを用いてStage単位での処理時間を確認しましたが、正直なところSpark自体を触り始めたばかりで、まだまだ理解が浅い部分があります。 以下の点は今後学びながら深掘りしていきたいです。 - Spark UIの詳細メトリクス(Scheduler Delay、GC Time、Shuffle Read/Write など)の読み方 - ワーカー2で逆転現象が起きる原因の特定 - ワーカータイプによる違い - Icebergのデータファイル形式(Parquet vs Avro)によるパフォーマンス差 引き続き検証を進めて、分かったことがあれば記事にしていきたいと思います。