---
title: AWSで実現する大規模データ保存・分散処理 ―IcebergとSparkの仕組みと実践―
tags:  #aws #大規模データ #s3 tables #glue spark job  
author: [Takuya Yamazaki](https://docswell.com/user/kkmtyyz)
site: [Docswell](https://www.docswell.com/)
thumbnail: https://bcdn.docswell.com/page/Y79PQW58E3.jpg?width=480
description: AWSで大規模データをS3 Tablesに保存し、Glue Spark Jobで効率よく分散処理する際の実践的なポイントを紹介しています。 S3 Tables・Glue Spark Jobを使いこなすため、元となっているIceberg・Sparkの仕組みから解説しています。
published: May 31, 26
canonical: https://docswell.com/s/kkmtyyz/KWRMXQ-2026-06-08-232449
---
# Page. 1

![Page Image](https://bcdn.docswell.com/page/Y79PQW58E3.jpg)

2026-05-26 AWSランチセッション 第18回
AWSで実現する大規模データ保存・分散処理
― IcebergとSparkの仕組みと実践 ―
山崎 拓也


# Page. 2

![Page Image](https://bcdn.docswell.com/page/G78DGNYZ7D.jpg)

山崎 拓也
所属: SIer
仕事:
• AWS案件のアプリやインフラのリード
• 社内AWSサポート
好き: 低レイヤ、SF、AWS
AWSアワード:
• 2026 AWS Community Builder (Serverless)
• 2024～2025 Japan AWS Top Engineer
• 2022～2025 Japan All AWS Certifications Engineer


# Page. 3

![Page Image](https://bcdn.docswell.com/page/L7LMGP41JR.jpg)

アジェンダ
• 仮想要件とアーキテクチャ
• Icebergの仕組み
• S3 Tablesの実践的なポイント
• Sparkの仕組み
• Glue Spark Jobの実践的なポイント
• まとめ


# Page. 4

![Page Image](https://bcdn.docswell.com/page/4EMYQ4K5EW.jpg)

仮想要件とアーキテクチャ


# Page. 5

![Page Image](https://bcdn.docswell.com/page/PER98WXZJ9.jpg)

沢山のデバイスから沢山のイベントデータが流れてくる
❶
1レコード5000カラム


# Page. 6

![Page Image](https://bcdn.docswell.com/page/P7XQ8P61EX.jpg)

デバイス毎にソートやレコードを跨ぐ変換、分岐、演算など複雑な処
理を行い、BI用データを作る
❶
❷
❸
•
•
•
•
•
100デバイス
5000カラム
600万レコード
1レコード25kB
wide table問題
❹
❺


# Page. 7

![Page Image](https://bcdn.docswell.com/page/37K9KD1M7D.jpg)

データはdevice_idごとにevent_timeでソートして処理する
❶
❷
❸
❹
❺
device_id
event_time
status
data_0001
data_0002
…
data_5000
device-001
2026-05-24 12:19:59.625769 UTC
on
11.9006
29.5572
…
83.8366
device-001
2026-05-24 12:19:59.622365 UTC
off
83.8306
74.4484
…
19.9301
device-001
2026-05-24 12:19:59.613774 UTC
off
4.4936
26.4307
…
6.6576
device-002
2026-05-24 12:22:19.437531 UTC
off
17.351
42.7808
…
59.7419
device-002
2026-05-24 12:22:19.436117 UTC
on
69.2087
28.331
…
2.6499


# Page. 8

![Page Image](https://bcdn.docswell.com/page/LJ3WZRQ2J5.jpg)

生データはCSVで取得したい
❶
❷
❸
❹
❺


# Page. 9

![Page Image](https://bcdn.docswell.com/page/8JDKRY96EG.jpg)

Iceberg、Sparkの大まかな仕組みを通して、
各部分の実践的なポイントを紹介
❶


# Page. 10

![Page Image](https://bcdn.docswell.com/page/VEPKW69Z78.jpg)

Icebergの仕組み


# Page. 11

![Page Image](https://bcdn.docswell.com/page/27VV83MM7Q.jpg)

Apache Iceberg とは
• 大規模な分析向けの高性能テーブルフォーマット
• データ配置を最適化し、大規模データをSQLで効率的にクエリ
• メタデータでテーブル情報や統計情報を管理
• カタログのメタデータポインタから、各ファイルを辿って物理データファイ
ルにアクセスする
Iceberg Table Spec：https://iceberg.apache.org/spec/


# Page. 12

![Page Image](https://bcdn.docswell.com/page/5JGL53GX7L.jpg)

データ操作の度にファイルが増えていく
• データ挿入の度に各種メタデータファイルとデータファイルが作成される
• データ削除はバージョンや戦略で異なる。更新は削除と挿入で行う
1データ目書き込み
1データ目データ
2データ目書き込み
2データ目データ
1データ目データ


# Page. 13

![Page Image](https://bcdn.docswell.com/page/47QYZ5X5EP.jpg)

メタデータポインタの楽観的同時実行制御により原子性を担保
• 複数のデータ操作が同時に行われた場合、各種メタデータファイルとデータ
ファイルがそれぞれ独立に作成される
• メタデータポインタの更新をcommitできるのは同時に1つの操作のみ
• commitできなかった操作は失敗するが、作成した各種ファイルは残る
Aの書き込み
によりファイル作成
同時
Bの書き込み
によりファイル作成
メタデータポインタを
更新できるのは同時に1操作のみ
（今回は操作B。Aは失敗）
後述の孤立ファイル削除にて削除


# Page. 14

![Page Image](https://bcdn.docswell.com/page/KE4W396VJ1.jpg)

データの物理配置はパーティションとソート順で設定できる
• 列の値に関数を適用してパーティション作成できる
• パーティション列はテーブルには不要（隠しパーティション）
• クエリ時もパーティションの指定不要
パーティション
含まれるデータの統計情報
event_time_day=2026-05-24,
device_id_bucket=9
device_id=
{min=device-013,
max=device-083},
event_time=
{min=2026-05-24 02:42:14… ,
max=2026-05-24 15:34:15…}, etc
event_time_day=2026-05-24,
device_id_bucket=8
device_id=
{min=device-015, max=device-071},
event_time=
{min=2026-05-24 02:42:14…,
max=2026-05-24 15:34:15…}, etc
device_idをHash関数で32分割


# Page. 15

![Page Image](https://bcdn.docswell.com/page/L71Y1KV4JG.jpg)

テーブルの状態把握でよく使うクエリ
• select * from &quot;device_events$snapshots&quot;;
• スナップショット情報
• $manifests
• マニフェストファイル情報
• $partitions
• パーティション情報
• $files
• データファイル情報


# Page. 16

![Page Image](https://bcdn.docswell.com/page/G7WG8DLZE2.jpg)

パフォーマンスを保つためのメンテナンス機能
No.
機能名
内容
❶
コンパクション
指定した戦略に基づいてデータをマージ・再配置する
❷
スナップショット削除
古いスナップショットを削除する
❸
孤立ファイル削除
参照されなくなったファイルを削除する
❷
❶
❸


# Page. 17

![Page Image](https://bcdn.docswell.com/page/4JZL8GMLE3.jpg)

Icebergの特徴的な機能
機能名
内容
隠しパーティション
パーティション列を意識せずにクエリ最適化できる仕組み
コンパクション
小さなファイルを再編成し読み取り効率を改善する機能
スキーマ進化
既存データを壊さずにテーブル定義を変更できる仕組み
パーティション変更・データ型拡張など
タイムトラベル
過去のスナップショット時点のデータをクエリできる機能
ブランチ
Gitのブランチのようにスナップショットを分岐できる機能


# Page. 18

![Page Image](https://bcdn.docswell.com/page/YE6WPYNMEV.jpg)

おすすめ書籍
• 実践Apache Iceberg
https://gihyo.jp/book/2025/978-4-297-15074-7
• ISBN
• 978-4-297-15074-7（紙）
• 978-4-297-15075-4（電子）


# Page. 19

![Page Image](https://bcdn.docswell.com/page/GE5MKG5QE4.jpg)

S3 Tablesの実践的なポイント


# Page. 20

![Page Image](https://bcdn.docswell.com/page/9729WYNWJR.jpg)

AWSでIcebergを使う際の選択肢
• S3 Tables or 自分で構築
S3 Tables
Glue DataCatalog &amp; S3 Bucket
管理方式
フルマネージド
自分で構築
設定の柔軟性
制限あり
高い
パフォーマンス
クエリが3倍高速
トランザクションは秒あたり10倍処理可能
-
コスト
メンテナンス
条件次第。比較が難しい。
（個人的にはそこまで変わらない気がする）
自動
• 比較はAWS Builder Centerの記事「Amazon S3 Tables vs Self-Managed
Apache Iceberg on S3: A Technical Deep-Dive for Startups」が非常に詳細
https://builder.aws.com/content/39n7WU54TBsV3OlKwtJsnL54PVL/amazon-s3-tables-vs-self-managedapache-iceberg-on-s3-a-technical-deep-dive-for-startups


# Page. 21

![Page Image](https://bcdn.docswell.com/page/DJY4LGP97M.jpg)

S3 Tablesの料金体系 小さなオブジェクト作成は避けると良い
• StandardとIntelligent Tieringがある
• モニタリングやコンパクションはオブジェクトごと課金
課金項目（Standard）
ストレージ
（月ごと）
種類
料金
最初の50TB
0.0288 USD/GB
次の450TB
0.0276 USD/GB
500TB以上
0.0265 USD/GB
リクエスト
（1000リクエストごと）
PUT, POST, LIST
0.0047 USD
GET, その他
0.00037 USD
モニタリング
（1000オブジェクトごと）
-
0.025 USD
コンパクション オブジェクト数
（処理された1000オブジェクトごと）
-
0.002 USD
コンパクション データ量
（処理されたGBごと）
Binpack
0.005 USD
Sort, Z-order
0.01 USD
Amazon S3 料金表：https://aws.amazon.com/jp/s3/pricing/


# Page. 22

![Page Image](https://bcdn.docswell.com/page/V7NY4G5DE8.jpg)

Firehoseを使って小さなファイル作成を避ける
• 小さなファイルが多いとパフォーマンス低下
• オブジェクト数で課金されるため、ファイルを大きく作ることでコスト削減
• Firehoseのバッファ設定を最大にする
• 15分
• 128 MiB
• Firehoseでの挿入でもIcebergパーティションどおり分割される
$snapshots の summary項目から抜粋
added-data-files=29,
added-records=37999,
total-records=54271500,
FIREHOSE-DELIVERY-STREAM-ID=…,
changed-partition-count=29,
FIREHOSE-INTERNAL-CHECKPOINT=…
1度の書き込みで、
37999レコードを
29パーティションに分け、
29ファイルとして作成


# Page. 23

![Page Image](https://bcdn.docswell.com/page/YJ9PQWY873.jpg)

運用用にGlue Spark Jobを1つ用意すると良い
• Athenaはサポートしていない機能がある
• テーブル作成時のソート順（致命的）
• TRUNCATEやメンテナンスプロシージャなど
• テーブル情報などの表示がSparkと比べて限定的
• ログに実行SQLと結果を出力して残すと良い
• SHOW TBLPROPERTIES の結果比較
Athena
Glue Spark Job
ソート順も出る


# Page. 24

![Page Image](https://bcdn.docswell.com/page/GJ8DGN6ZJD.jpg)

S3 Tablesのコンパクション戦略はソート順が使われる
• 選択できるコンパクション戦略は３つ
コンパクション戦略
内容
Binpack
ファイルサイズのみで最適化
Sort
ソート順の1カラムでソートしつつ最適化
Z-order
ソート順の複数カラムを加味しつつ最適化
Athenaはソート順未サポートなので
Glue Spark Jobからテーブル作成する
• コンパクション前後のデータ構造変化（$snapshotsより抜粋）
committed_at
operation
summary
2026-05-24 18:04:21.235 UTC
replace
added-data-files=2, added-records=4280151, deleteddata-files=344, deleted-records=4280151, totalrecords=50994000, changed-partition-count=2, totalfiles-size=944817544, total-data-files=58
…
2026-05-24 18:03:42.855 UTC
append
added-data-files=29, records=38499, totalrecords=50994000, changed-partition-count=29, totalfiles-size=995207031, total-data-files=5470,


# Page. 25

![Page Image](https://bcdn.docswell.com/page/LJLMGP91ER.jpg)

timestamp型のz-orderはタイムゾーン必須
• タイムゾーン無しtimestamp_ntzの場合、コンパクション時にエラーとなる
• Glue Spark Jobではtimestamp型は暗黙的にtimestamp_ltzとなる


# Page. 26

![Page Image](https://bcdn.docswell.com/page/47MYQ4Z57W.jpg)

コンパクション実行履歴はメトリクスや$snapshotsから確認
• メトリクス
• CompactionObjectsCount_z-order （処理されたオブジェクト数）
• CompactionBytesProcessed_z-order （処理されたデータサイズ）
• コンソールで成功でも、コンパクション不要な場合は実行されていない
成功でも処理実行されていないため、
課金されない


# Page. 27

![Page Image](https://bcdn.docswell.com/page/P7R98W6ZE9.jpg)

カラム数によるパフォーマンス検証 7カラム vs 5003カラム
• カラム数が多い場合、データ処理が平均32秒遅かった
• Icebergからのデータ読み込み時のSparkパーティション数に大きな差
7カラム
必要カラムのみ
Select
パーティション
ソート順
コンパクション戦略
同じ
（コンパクション済み）
レコード数
repartitionして
データ処理
5003カラム
6,000,000レコード
平均データ処理時間
2分8秒
2分40秒
Icebergパーティション数
58
87
読み込み時
Sparkパーティション数
37
1694


# Page. 28

![Page Image](https://bcdn.docswell.com/page/PJXQ8PM17X.jpg)

カラム数が多い場合、Icebergからのデータ読み込みが34秒遅い
• Selectカラム数が同じでもパーティションが多くなり、読み込みタスクが細
切れになるため時間が多くかかる
• repartition後のデータ処理時間は同じため、カラムが多くても全体影響はほ
とんどない
7カラム
2026-05-28T14:35:18,113 34810
2026-05-28T14:35:32,359 49056
Starting task 0.0 in stage 0.0
Finished task 28.0 in stage 0.0 (executor 2) (37/37)
5003カラム
2026-05-28T14:30:20,146 34306
2026-05-28T14:31:08,347 82507
Starting task 0.0 in stage 0.0
Finished task 1691.0 in stage 0.0 (executor 4) (1694/1694)


# Page. 29

![Page Image](https://bcdn.docswell.com/page/3JK9KDGMJD.jpg)

生データ保存用とデータ処理用でテーブルを分ける選択肢もある
• データ処理では必要列のみ利用するケースが多い
• クエリパターンに応じたパーティションやコンパクション戦略をとれる
データ処理用テーブル
生データテーブル
7
5003
パーティション
days(event_tme),
bucket(32, device_id)
days(event_time)
ソート順
device_id,
event_time
device_id
コンパクション戦略
Z-order
Sort
カラム数


# Page. 30

![Page Image](https://bcdn.docswell.com/page/LE3WZRN2E5.jpg)

用途に応じてAthenaとGlue Spark Jobを使い分ける
• 生データテーブルからの単一CSVファイル作成はAthenaを使う
• データ処理や運用作業にはGlue Spark Jobを使う
検証では23.5GBのクエリ結果でも
1つのCSVファイルとして作成された


# Page. 31

![Page Image](https://bcdn.docswell.com/page/8EDKRYW67G.jpg)

Iceberg バージョン3を使用するには format-version を指定する
• デフォルトはIcebergバージョン2
• バージョン3は新しい仕組みや機能が利用できる
Apache Iceberg V3 の使用：https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/userguide/working-with-apache-iceberg-v3.html


# Page. 32

![Page Image](https://bcdn.docswell.com/page/V7PKW6XZJ8.jpg)

Sparkの仕組み


# Page. 33

![Page Image](https://bcdn.docswell.com/page/2JVV83LMJQ.jpg)

Apache Spark とは
• 大規模データを高速に処理するための分散処理エンジン
• Driverノード1つ、Workerノード複数
• Driverがデータ処理の実行計画を立て、ExecutorへTaskとして配布する
• データをSparkパーティションとして分割し、複数ノードで並列処理する


# Page. 34

![Page Image](https://bcdn.docswell.com/page/5EGL53XXJL.jpg)

Actionが実行されるまで、データロードや処理は実行されない
• Transformation と Action の2種類のメソッドがある
• Transformationメソッドは実行計画の作成のみ行う（遅延評価）
• map()
• filter()
• groupByKey()
• repartition()
• Actionメソッドで実行計画が初めて実行される
• reduce()
• collect()
• count()
• save()


# Page. 35

![Page Image](https://bcdn.docswell.com/page/4JQYZ5857P.jpg)

遅延評価をコードで確認
❶
❶ select/filterを行い、DataFrame定義しても、
まだデータはロードされない
❷
❸
❷ groupBy/agg/orderByをしても、
まだ実行されない
❸ show()により、
ここで初めて実際のロード・変換・集計が実行。
各ExecutorにTask配布して分散実行される


# Page. 36

![Page Image](https://bcdn.docswell.com/page/K74W392VE1.jpg)

データの分散単位はSparkパーティション
• ロード時、データは複数の Spark パーティションへ分散される
• ロード時のパーティション配置は処理内容に最適化されているとは限らない
• 処理パターンに合わせて、repartition() によりデータを再分散する
repartition(&quot;device_id&quot;)
実際は偏りをなくすため
パーティション数を指定し、
ハッシュ関数で均等に分散させる
repartition(40, &quot;device_id&quot;)


# Page. 37

![Page Image](https://bcdn.docswell.com/page/LJ1Y1KM4EG.jpg)

パフォーマンスに影響する注意が必要な操作
• WorkerからDriverに全てのデータを集める
• collect()
• toPandas()
• シャッフル。ノード間やパーティション間でデータを再分配する操作
• groupByKey()
• orderBy()
• repartition()
特にシャッフルは生じやすいので注意


# Page. 38

![Page Image](https://bcdn.docswell.com/page/GJWG8D3Z72.jpg)

再利用するDataFrameはキャッシュに乗せる
• キャッシュしない限り、アクションごとにDataFrameが再計算される
• df.cache()：アクション実行後、Executorのキャッシュに乗せる
• df.unpersist()：キャッシュから降ろす


# Page. 39

![Page Image](https://bcdn.docswell.com/page/4EZL8GVL73.jpg)

パーティションごとに任意の関数で分散処理する
• df.rdd.mapPartitions(func)
• パーティションのレコードをループしたい場合
• func()にはパーティション内レコードのiteratorが渡される
• df.mapInPandas(func, schema=...)
• パーティションをPandas DataFrameとして扱いたい場合
• func()にはPandas DataFrameのiteratorが渡される


# Page. 40

![Page Image](https://bcdn.docswell.com/page/Y76WPY5M7V.jpg)

Glue Spark Jobの実践的なポイント


# Page. 41

![Page Image](https://bcdn.docswell.com/page/G75MKGYQ74.jpg)

Workerノードのオートスケーリング設定ができる
• オートスケーリングしない場合、ノードが余るとコストが余計にかかる
オートスケーリング 料金
無効（デフォルト） 設定したワーカー数 × ワーカータイプのDPU × 実行時間
有効
実際に使用したDPU
• ConnectionでVPC接続する場合、ノード毎にENI作成されるためIP数に注意
Worker type specifications table：
https://docs.aws.amazon.com/glue/latest/dg/work
er-types.html#worker-type-specifications


# Page. 42

![Page Image](https://bcdn.docswell.com/page/9J29WYGWER.jpg)

CloudWatchログはDriver、Executorごとにストリームが分かれる
• 基本的にログは全て /aws-glue/jobs/error ロググループに出力（変更可）
• Workerノードごとに必ず１つのExecutor。本当に便利
Driver
Executor
Workerノード数
と等しい
• 各TaskのパーティションIDなどの情報はTaskContextから取得できる
Worker type specifications table：https://docs.aws.amazon.com/glue/latest/dg/worker-types.html#worker-type-specifications


# Page. 43

![Page Image](https://bcdn.docswell.com/page/DEY4LGV9JM.jpg)

コンソールのSpark UIから詳細なパフォーマンスが確認できる
• タスク数やどの処理に時間がかかっているのかなど


# Page. 44

![Page Image](https://bcdn.docswell.com/page/VJNY4GMD78.jpg)

Icebergパーティション通りのSparkパーティションになる保証はない
• 処理パターンに最適化するにはrepartition()が必要
• 検証時、コンパクション前は同一device_idがパーティションを跨いでロー
ドされた
• コンパクション後は同一device_idが同一パーティションに綺麗にロードさ
れたが、保証はない
• パーティション分割数は、Executorの総CPUコア数より多めに設定し、継続
的にタスクが割り当たるようにする
Worker type specifications table：
https://docs.aws.amazon.com/glue/latest/dg/work
er-types.html#worker-type-specifications


# Page. 45

![Page Image](https://bcdn.docswell.com/page/YE9PQWN8J3.jpg)

Redshiftへの書き込みもExecutorを使って効率よく行う
• Driverに集めない
• 処理後データは各ExecutorからS3へ出力される
• Driverからの1度のCOPYクエリ実行でRedshiftへ書き込まれる
• S3の出力ファイルは自動削除されないためライフサイクルで消す必要あり


# Page. 46

![Page Image](https://bcdn.docswell.com/page/GE8DGNKZED.jpg)

デバイスID毎、イベント時間順に分散データ処理する際の例
パーティション分割、
ソート、複雑な処理
処理日時列を追加
save() がアクション


# Page. 47

![Page Image](https://bcdn.docswell.com/page/LELMGPZ17R.jpg)

まとめ
• IcebergもSparkも、仕組みを理解して上手く使うことが大切
• S3 Tablesへの挿入はFirehoseを使って料金と効率を最適化
• Glue Spark Jobはパーティションとアクション・シャッフルを意識する


# Page. 48

![Page Image](https://bcdn.docswell.com/page/4JMYQ4V5JW.jpg)

ご清聴ありがとうございました。


