【AWS】Iceberg × Data Firehose ストリーミング取り込み — CDC パイプラインとコンパクション戦略
はじめに
第 1 弾「Apache Iceberg 実践入門」では Iceberg の基本概念と Athena での操作を、第 2 弾「運用コスト最適化」ではコンパクションやスナップショット管理を中心としたコスト最適化を解説しました。
ここまではバッチ処理を前提に話を進めてきましたが、実際のデータ基盤ではリアルタイムにデータを取り込みたいという要件が頻繁に発生します。
- 業務データベースの変更をデータレイクにリアルタイム反映したい
- IoT デバイスやアプリケーションログを即座に分析可能にしたい
- 日次バッチの待ち時間をなくし、ダッシュボードの鮮度を上げたい
AWS 環境では Amazon Data Firehose が Iceberg テーブルへのストリーミング配信をネイティブサポートしており、フルマネージドなリアルタイム取り込みパイプラインを構築できます。
この記事では、Data Firehose の Iceberg 配信機能を軸に、CDC(Change Data Capture:データベースの変更をリアルタイムにキャプチャする仕組み)パイプラインのアーキテクチャパターン比較と、ストリーミング取り込み特有のコンパクション戦略を解説します。
この記事で得られること:
- Data Firehose → Iceberg の構成オプション(ソース選択、バッファリング、動的ルーティング)
- CDC パイプライン 4 パターンのアーキテクチャ・コスト・適用条件の比較
- ストリーミング取り込み時のスモールファイル問題とコンパクション戦略
- ユースケース別の推奨アーキテクチャ
前提: 料金は US East (N. Virginia) リージョン、2026 年 2 月時点の公開価格です。
Data Firehose × Iceberg の基本構成
対応ソースとスループット
Amazon Data Firehose は 2024 年 10 月に Apache Iceberg テーブルへの配信をサポートしました。以下の 4 つのソースからデータを取り込み、Iceberg テーブル(汎用 S3 バケットまたは S3 Tables)に書き込めます。
| ソース | 特徴 | スループット上限 |
|---|---|---|
| Direct PUT | SDK / API でアプリケーションから直接送信 | 5 MiB/s(US East 等)、1 MiB/s(他リージョン) |
| Kinesis Data Streams | KDS シャードからの読み取り | KDS のシャード数に依存 |
| Amazon MSK | Kafka トピックからの読み取り | MSK クラスタの容量に依存 |
|
|
Direct PUT はセットアップが最も簡単ですが、初期値 5 MiB/s の制限があります。スロットリングが発生すると Firehose が自動的にスループットを引き上げますが、大量ストリーミングでは Kinesis Data Streams を経由する構成が確実です。
バッファリング設定 — レイテンシ vs ファイルサイズのトレードオフ
Firehose はデータを一定量(サイズ)または一定時間(間隔)でバッファリングしてから Iceberg テーブルにコミットします。この設定がストリーミング環境のファイルサイズとクエリ性能を大きく左右します。
| パラメータ | 範囲 | デフォルト | 説明 |
|---|---|---|---|
| Buffer size | 1〜128 MiB | 128 MiB | 大きいほどファイルが大きくなり、コンパクション負荷が減る |
| Buffer interval | 0〜900 秒 | 300 秒 | 小さいほどレイテンシが下がるが、スモールファイルが増える |
いずれかの条件を先に満たした時点で Iceberg テーブルへの書き込みが実行されます。
注意: Buffer interval を 60 秒未満(0 秒含む)に設定すると、S3 マルチパートアップロードが使用され、S3 PUT API コストが増加します。第 2 弾で解説した S3 API コストの観点も考慮して設定してください。
レイテンシ要件別の設定指針:
| 要件 | Buffer size | Buffer interval | 想定ファイル数/日 |
|---|---|---|---|
| ニアリアルタイム(〜1 分) | 128 MiB | 60 秒 | ~1,440 |
| 標準(〜5 分) | 128 MiB | 300 秒 | ~288 |
| バッチ寄り(〜15 分) | 128 MiB | 900 秒 | ~96 |
Buffer size はできる限り 128 MiB(最大値)に設定するのがベストプラクティスです。データ量が少なく 128 MiB に達しない場合は Buffer interval で書き込みタイミングが決まるため、実質的に interval の設定がレイテンシを制御します。
動的ルーティング — JSONQuery によるマルチテーブル配信
1 つの Firehose ストリームから複数の Iceberg テーブルにレコードを振り分けられます。CDC パイプラインで特に有効な機能です。
CDC ソースから流れてくるレコードの例と、対応する JSONQuery 式を示します。
DMS 経由の CDC レコード例:
{
"table_name": "orders",
"op": "update",
"data": {
"order_id": "ORD-001",
"status": "shipped",
"updated_at": "2026-01-15T10:30:00Z"
}
}
JSONQuery 式:
{
"DestinationDatabaseName": "my_database",
"DestinationTableName": "$.table_name",
"Operation": "$.op"
}
この例では、レコードの table_name フィールドから配信先テーブル(orders)を、op フィールドから操作種別(update)を動的に取得します。
-
DestinationDatabaseName: 静的な値またはレコード内の JSON フィールドを指定 -
DestinationTableName: レコード内のフィールドから動的に取得(例:$.table_name) -
Operation:insert(デフォルト)/update/deleteを指定
CDC ソースから流れてくるイベントには通常テーブル名と操作種別が含まれるため、JSONQuery 式でそのまま抽出するだけでマルチテーブルの INSERT/UPDATE/DELETE を自動適用できます。
注意点:
-
update/delete操作を使用するには、対象テーブルにユニークキーの設定が必須です - ユニークキーが未設定の場合、レコードはエラーバケット(S3)に配信されます
Lambda 変換との組み合わせ
Firehose の Lambda 変換機能と動的ルーティングを併用する場合、優先順位は以下の通りです:
- Lambda 出力のメタデータフィールドを最優先でチェック
- メタデータがない場合、JSONQuery 式でフォールバック
複雑な変換ロジック(フィールドの正規化、エンリッチメント等)を Lambda で実行しつつ、ルーティングも柔軟に制御できます。
料金
Firehose の Iceberg 配信は、ソースによらず $0.045/GB(US East)で統一されています。
| ソース | 単価 |
|---|---|
| Direct PUT → Iceberg | $0.045/GB |
| Kinesis Data Streams → Iceberg | $0.045/GB |
| MSK → Iceberg | $0.045/GB |
Iceberg 配信では 5 KB 単位の切り上げがなく、実際のデータ量で課金されます。月間 100 GB のストリーミングデータなら Firehose の料金は ~$4.50/月です。
CDC パイプライン — 4 つのアーキテクチャパターン
業務データベース(MySQL / PostgreSQL 等)の変更をリアルタイムに Iceberg テーブルへ反映する CDC パイプラインは、AWS 上で 4 つのアーキテクチャパターンで構築できます。
パターン 1: DMS + KDS + Firehose(GA)
最も実績のあるパターンです。AWS DMS が RDB から CDC イベントをキャプチャし、Kinesis Data Streams に書き込み、Firehose が Iceberg テーブルに配信します。
Source DB → AWS DMS(CDC Task)→ Kinesis Data Streams → Firehose → Iceberg Tables
メリット:
- 全コンポーネントが GA(本番利用可能)
- DMS が多数のソース DB をサポート(Oracle、SQL Server、MongoDB 等)
- KDS のバッファリングにより耐障害性が高い
- aws-samples に CDK リファレンス実装あり
デメリット:
- 3 つのサービスを管理する必要がある
- DMS のレプリケーションインスタンス(または DMS Serverless)のコストが加算
- セットアップが複雑
コスト概算(月間 100 GB の CDC データ):
| コンポーネント | 概算月額 |
|---|---|
| DMS Serverless(2 DCU = DMS Capacity Unit) | ~$100($0.0694/DCU-hour × 2 DCU × 720h) |
| Kinesis Data Streams(1 シャード) | ~$36($0.015/シャード時間 × 720h + PUT 料金) |
| Firehose(Iceberg 配信) | ~$4.50($0.045/GB × 100 GB) |
| 合計 | ~$141 |
パターン 2: Firehose Database Source(廃止)
⚠️ 廃止: 2024 年 11 月にプレビュー公開された機能ですが、プレビューは 2025 年 9 月 30 日に終了し、GA には至らず廃止されました。
Firehose が直接 RDB に接続し、DMS・KDS 不要で CDC パイプラインを ~$4.50/月で構築できる構成でした。2025 年 9 月 17 日に廃止が通知され、同月末にコンソールから機能が削除されています(AWS ドキュメントページは残存していますが、新規作成は不可)。エンドツーエンドのマネージド CDC という方向性は、今後の AWS サービス進化において引き続き重要なテーマです。現時点ではパターン 1 が CDC の標準構成です。
パターン 3: MSK (Debezium) + Glue Streaming
Kafka エコシステムを活用するパターンです。MSK Connect で Debezium コネクタをデプロイし、CDC イベントを MSK トピックに配信。Glue Streaming ETL(Spark)が Iceberg テーブルに書き込みます。
Source DB → MSK Connect(Debezium)→ MSK → Glue Streaming ETL(Spark)→ Iceberg Tables
メリット:
- 既存の Kafka 基盤がある場合に統合しやすい
- Glue Streaming の Spark ベースの変換で複雑なロジックが可能
- Debezium のスキーマレジストリ連携
デメリット:
- MSK クラスタ + MSK Connect + Glue Streaming の管理が必要
- MSK クラスタの固定費用が高い
- セットアップが最も複雑
コスト概算(月間 100 GB の CDC データ):
| コンポーネント | 概算月額 |
|---|---|
| MSK Serverless | ~$150 |
| MSK Connect(Debezium) | ~$50 |
| Glue Streaming ETL(2 DPU) | ~$100 |
| 合計 | ~$300+ |
パターン 4: MSK + Firehose
パターン 3 の簡易版です。MSK からの読み取りを Glue Streaming ではなく Firehose で行います。Spark の複雑な変換が不要で、Firehose の動的ルーティングで十分な場合に適しています。
Source DB → MSK Connect(Debezium)→ MSK → Firehose → Iceberg Tables
メリット:
- Kafka エコシステム + Firehose のシンプルさを両立
- Glue Streaming が不要でコスト削減
- Firehose の動的ルーティングでマルチテーブル配信が容易
デメリット:
- MSK クラスタの固定費用は依然として高い
- Glue Streaming ほどの柔軟な変換はできない
コスト概算(月間 100 GB の CDC データ):
| コンポーネント | 概算月額 |
|---|---|
| MSK Serverless | ~$150 |
| MSK Connect(Debezium) | ~$50 |
| Firehose(Iceberg 配信) | ~$4.50 |
| 合計 | ~$205 |
パターン比較サマリー
| パターン 1 | パターン 2 | パターン 3 | パターン 4 | |
|---|---|---|---|---|
| 構成 | DMS + KDS + Firehose | Firehose DB Source | MSK + Glue Streaming | MSK + Firehose |
| 複雑さ | 中 | 低 | 高 | 中 |
| 月額(100 GB) | ~$141 | ~$4.50 | ~$300+ | ~$205 |
| 本番利用 | GA | 廃止 | GA | GA |
| 対応 DB | 多数 | MySQL/PgSQL | Debezium 対応全 DB | Debezium 対応全 DB |
| 変換の柔軟性 | Lambda 変換 | 限定的 | Spark(高い) | Lambda 変換 |
選定ガイド:
- 今すぐ本番で使いたい(MySQL/PostgreSQL) → パターン 1(DMS + KDS + Firehose)
-
コストを最小化したい→パターン 2(Firehose Database Source)(廃止済み。現時点ではパターン 1 が最もコスト効率の良い GA 構成) - 既存 Kafka 基盤を活用 + 複雑な変換が必要 → パターン 3(MSK + Glue Streaming)
- 既存 Kafka 基盤を活用 + シンプルな配信 → パターン 4(MSK + Firehose)
ストリーミング取り込みのコンパクション戦略
ストリーミング取り込み環境では、第 2 弾「運用コスト最適化」で解説したコンパクションがさらに重要になります。バッチ取り込みとは異なる課題と対策が必要です。
スモールファイル問題の定量化
Firehose のバッファリング間隔ごとに新しいデータファイルが生成されます。放置するとどうなるか、数字で確認します。
| バッファ間隔 | ファイル数/日 | ファイル数/月 | 1 ヶ月後のスキャン影響 |
|---|---|---|---|
| 60 秒 | 1,440 | ~43,200 | メタデータ読み取りだけで数秒〜十数秒 |
| 300 秒(デフォルト) | 288 | ~8,640 | クエリ性能の明らかな劣化 |
| 900 秒 | 96 | ~2,880 | 影響は小さいが蓄積は進む |
Iceberg はファイルごとにメタデータ(min/max 統計、パーティション情報)を管理するため、ファイル数の増加はメタデータ読み取りコストに直結します。コンパクションなしのストリーミング運用は現実的ではありません。
用語: スモールファイル問題の詳細と対処法は第 2 弾「運用コスト最適化」で解説しています。
コンパクション方式の選択
ストリーミング環境では、自動的かつ継続的にコンパクションを実行する仕組みが必要です。
| 方式 | ストリーミング適性 | 特徴 |
|---|---|---|
| Glue 自動コンパクション | 最適 | パーティション単位で自動監視、100 ファイル超で自動トリガー |
| S3 Tables 自動コンパクション | 最適 | 完全自動・設定不要。S3 Tables 利用時のみ |
| EMR Spark カスタムジョブ | 可 | パーティション認識型の細かい制御が可能。大規模・高頻度向け |
| Athena OPTIMIZE | 不向き | 手動実行、スキャン課金あり。バッチ環境向け |
Glue 自動コンパクションの活用
ストリーミング環境の標準的なコンパクション手段は AWS Glue 自動コンパクションです。
自動トリガーの条件:
- パーティション内のファイルが 100 ファイル超
- 各ファイルがターゲットサイズの 75% 未満
この 2 つの条件を両方満たすと、Glue がバックグラウンドでコンパクションを自動実行します。
対応する戦略:
| 戦略 | 用途 |
|---|---|
| Binpack | ファイルサイズの均一化(最も一般的) |
| Sort | 特定カラムでソートしてデータスキップ効率を向上 |
| Z-order | 複数カラムのクエリパターンに対応 |
ストリーミング環境では、まず Binpack でスモールファイル問題を解消し、クエリパターンが確定してから Sort や Z-order を検討するのが実用的です。
MoR(Merge-on-Read)のコンパクション:
MoR テーブルでは UPDATE/DELETE 時に Delete File が生成されます。Glue 自動コンパクションは Delete File のマージ(Data File への統合)にも対応しており、CDC ワークロードで MoR を使用する場合も自動でクリーンアップされます。
パーティション認識型コンパクション — ホット/ウォーム/コールド
ストリーミング環境で最も重要な設計原則は、現在書き込み中のパーティション(ホットパーティション)をコンパクション対象から除外することです。
| パーティション状態 | 説明 | コンパクション |
|---|---|---|
| ホット(現在の時間) | 書き込み中 | 対象外 |
| ウォーム(1 時間前) | 遅延データの可能性 | 対象外 |
| コールド(2 時間以上前) | 書き込み完了 | 対象 |
なぜホットパーティションを除外するのか:
- Iceberg は楽観的同時実行制御を採用しています。書き込みとコンパクションが同じパーティションで競合すると、コミット失敗 → リトライが発生します
- リトライ回数が増えるとスループットが低下し、最悪の場合データの到達遅延が拡大します
- コールドパーティションのみを対象にすることで、書き込みとの競合を完全に回避できます
Glue 自動コンパクションはパーティション単位で監視するため、ホットパーティションのファイル数が閾値に達する前にコールドパーティションへ移行していれば、自然とこのパターンに沿った動作になります。バッファ間隔のチューニングでホットパーティション内のファイル数を制御することが重要です。
圧縮コーデックの選択
ストリーミング環境では、書き込み時とコンパクション後で異なるコーデックを使い分けるのがベストプラクティスです。
| フェーズ | 推奨コーデック | 理由 |
|---|---|---|
| 書き込み時(Firehose) | Snappy | 圧縮/展開が高速。スモールファイルはコンパクションで再書き込みされるため、圧縮率より速度を優先 |
| コンパクション後 | ZSTD | 長期保存データは圧縮率を重視。Snappy 比で 20〜30% 程度ストレージ削減 |
Iceberg はファイルごとに異なるコーデックを保持できるため、コンパクション時にコーデックを変更しても既存のクエリに影響はありません。
推奨アーキテクチャ
ユースケース別の構成パターン
CDC パイプラインに加え、アプリケーションログや IoT データの直接ストリーミングでも同じ Firehose → Iceberg 構成が有効です。代表的な 4 つのユースケースを紹介します。
ユースケース 1: RDB の CDC → Iceberg(本番環境、今すぐ始めたい)
パターン 1(DMS + KDS + Firehose)を採用。メンテナンスは Glue 自動コンパクション + Athena VACUUM で構成。
- パターン 1(DMS + KDS + Firehose)を採用
- Firehose の Buffer size: 128 MiB、Buffer interval: 300 秒
- Glue 自動コンパクション(Binpack、ターゲット 128〜256 MB)
- Athena VACUUM を日次実行(コンピュート無料)
ユースケース 2: RDB の CDC → Iceberg(コスト最小化) — Firehose Database Source 廃止により現在は利用不可。パターン 1 を推奨。
ユースケース 3: アプリケーションログ / IoT データのストリーミング
アプリケーションや IoT デバイスから KDS 経由で Firehose → Iceberg に配信。
- Direct PUT のスループット制限(5 MiB/s)を回避するため KDS を経由
- 動的ルーティングでイベントタイプ別にテーブルを分割
ユースケース 4: 既存 Kafka 基盤を活用した CDC
パターン 4(MSK + Firehose)を採用。
- パターン 4(MSK + Firehose)を採用
- 既に MSK クラスタが存在する場合に追加コストが最小
- 複雑な変換が必要なら Glue Streaming(パターン 3)に切り替え
運用チェックリスト
Firehose の設定:
- Buffer size は 128 MiB(最大値)に設定しているか
- Buffer interval はレイテンシ要件に合わせて調整しているか
- CDC データの場合、動的ルーティングで Operation(insert/update/delete)を指定しているか
- 対象テーブルにユニークキーを設定しているか(UPDATE/DELETE 使用時)
コンパクション:
- Glue 自動コンパクション(または S3 Tables 自動コンパクション)を有効にしているか
- コンパクション戦略は Binpack を基本とし、クエリパターンに応じて Sort/Z-order を検討
- ホットパーティションとコンパクションの競合を回避する設計になっているか
メンテナンス:
- Athena VACUUM を定期実行(日次推奨)してスナップショットと孤立ファイルを削除しているか
- 圧縮コーデックは書き込み時 Snappy、コンパクション後 ZSTD を使い分けているか
監視:
- Firehose の CloudWatch メトリクス(DeliveryToIceberg.Success、DeliveryToIceberg.Records)を監視しているか
- コンパクション前後のファイル数・サイズを定期的に確認しているか
まとめ
Data Firehose の Iceberg ネイティブ配信により、AWS 環境でのストリーミング取り込みがフルマネージドに実現できるようになりました。
CDC パイプラインの選定フロー:
| 条件 | 推奨パターン | 月額概算 |
|---|---|---|
| MySQL / PostgreSQL のみ | パターン 1(DMS + KDS + Firehose) | ~$141 |
| 既存 Kafka 基盤なし | パターン 1(DMS + KDS + Firehose) | ~$141 |
| 既存 Kafka + 複雑な変換 | パターン 3(MSK + Glue Streaming) | ~$300+ |
| 既存 Kafka + シンプルな配信 | パターン 4(MSK + Firehose) | ~$205 |
ストリーミング取り込みの 3 つの原則:
- バッファリングを最大化する — Buffer size 128 MiB でスモールファイルの生成を抑制
- コンパクションを自動化する — Glue 自動コンパクション(または S3 Tables)で継続的にファイルを統合
- ホットパーティションを保護する — 書き込み中のパーティションをコンパクション対象から除外し、競合を回避
Firehose Database Source はプレビュー段階で廃止されましたが、エンドツーエンドのマネージド CDC という方向性は AWS のサービス進化において引き続き重要です。現時点ではパターン 1(DMS + KDS + Firehose)が CDC パイプラインの標準構成であり、既存の Kafka 基盤がある場合はパターン 4 を検討します。
Iceberg シリーズ:
- Apache Iceberg 実践入門 — Athena で始めるモダンデータレイクの設計と運用
- Iceberg テーブルの運用コスト最適化 — コンパクション・メンテナンス・ストレージ戦略
- Iceberg × Data Firehose ストリーミング取り込み — CDC パイプラインとコンパクション戦略 ← 本記事
- Iceberg データレイクハウスの高度な設計 — Lake Formation・マルチエンジン連携・本番運用
- S3 Tables と SageMaker Lakehouse で進化する Iceberg データレイク — 自動最適化とコスト分析