AWS Glue + Iceberg で電力データを取り込み、処理時間を計測してみた
公開日 |
2026-01-29 |
掲載 |
ENECHANGE Developer Blog |
出典 |
はじめに
以下の記事で、AWS Glue と Iceberg を用いて分析基盤を作成してみました。 本記事では、この分析基盤に対して 1万〜15万件 のデータを取り込み、以下の観点で検証します。
Glue Job の処理時間(XML パース → Iceberg MERGE)の計測
データ量に対する処理時間のスケーリング傾向の把握
ワーカー数(並列度)による効果の確認
電力使用量データ量 と AWS Glue ワーカー数
1. 電力使用量データ量(ファイル数)
1日分の需要家数を1万件、2万件、5万件、10万件、15万件と変動させます。
1ファイル = 1万需要家(重複なし)分の 1日の電力使用量を保存しています。
ファイル数 |
需要家数 |
|---|---|
1 |
1万 |
2 |
2万 |
5 |
5万 |
10 |
10万 |
15 |
15万 |
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 で取得:
aws glue get-job-runs --job-name consumption-xml-to-iceberg --max-results 10
検証手順
1. サンプルデータ生成
以下の構造で、1万件分の電力使用量データを含むXMLファイルを生成します。
<?xml version="1.0" encoding="UTF-8"?>
<electricity_usage_report>
<record>
<external_id>CUST-001234</external_id>
<target_date>2024-01-15</target_date>
<updated_at>2024-01-16T06:30:00+09:00</updated_at>
<usage_kwh>
<slot time="00:00">1.2</slot>
<slot time="00:30">1.1</slot>
<!-- ... 48コマ ... -->
<slot time="23:30">1.3</slot>
</usage_kwh>
</record>
<record>
<external_id>CUST-001235</external_id>
<target_date>2024-01-15</target_date>
<updated_at>2024-01-16T06:30:00+09:00</updated_at>
<usage_kwh>
<slot time="00:00">1.2</slot>
<slot time="00:30">1.1</slot>
<!-- ... 48コマ ... -->
<slot time="23:30">1.3</slot>
</usage_kwh>
</record>
</electricity_usage_report>
2. テスト実行
テストは以下の手順で進めます。
S3 へアップロード
Iceberg テーブルのクリーンアップ
Glue Job 実行(ワーカー数を指定)
処理時間の計測
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の差が顕著になります。
以下のグラフは、需要家数の増加に伴う処理時間の変化を可視化したものです。
需要家数 |
ファイル数 |
ワーカー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 |
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回目 |
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ファイル です。
需要家数 |
ファイル数 |
ワーカー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 分析
Stage 比較: 1ファイル vs 15ファイル分割
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)
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)によるパフォーマンス差
引き続き検証を進めて、分かったことがあれば記事にしていきたいと思います。