Aurora→Redshift Zero-ETL、4時間のバッチが15分になった話
毎日4時間のETLバッチに頭を抱えてた僕たちが、Zero-ETL統合を導入したら想像以上に便利でした。実装のハマりどころと解決策を実体験で共有します。
Aurora→RedshiftのETL地獄から解放された話
うちのチームでは今年の初頭まで、Aurora PostgreSQLのデータをS3経由でRedshiftに毎日4時間かけてロードしてたんです。Lambda関数とGlueジョブを何個も組み合わせて、それなりに複雑な仕組みになってました。
先月、チーム全体のデータパイプラインを見直す時間が取れたから、思い切ってAWSが提供し始めたZero-ETL統合機能を試してみることにした。正直、「本当にマジでE抜きで動くのか?」って感じで懐疑的だったんですが、実装してみたら想像以上に便利で、今ではこの機能なしには戻れません。
Zero-ETLって実際のところ何ができるのか
2024年後半から一般提供が始まったZero-ETL統合は、Aurora PostgreSQLのデータをほぼリアルタイムにRedshiftに同期する機能だ。これまでのETLパイプラインの複雑なジョブは不要になります。
重要なのは「ETL処理を書かない」って言っても、単にデータをそのままコピーするわけじゃないということ。Auroraで更新されたテーブルの変更行のみをRedshiftに自動反映するから、スキーマ進化にも対応してるし、削除も含めた全操作が追跡される。
うちの場合、Auroraにはオンライン取引データ(注文、ユーザー情報)があって、Redshiftではそれをベースに分析用のデータマートを作ってた。以前は毎日21時に4時間のバッチが走ってて、朝8時にようやく前日データが使える状態になってました。これがホント地味にストレスだったんですよね。
従来のパイプライン vs Zero-ETL:
| 項目 | 従来方式 | Zero-ETL |
|---|---|---|
| データフロー | Aurora → Lambda → S3 → Glue → Redshift | Aurora → Redshift |
| 処理時間 | 約4時間 | 数秒以内 |
| ストレージ管理 | S3テンポラリ管理が煩雑 | 不要 |
| スキーマ更新 | 手動でマッピング修正 | 自動反映 |
| 削除操作の追跡 | 困難 | 自動追跡 |
実装の流れ:予想外に簡単だった
うちが実装したのはこんな流れです。
1. Auroraクラスタの設定確認
まずはAuroraのバージョン確認。Zero-ETL統合対応には Aurora PostgreSQL 14.6以降が必要。うちは既に15.2を使ってたから問題なし。
# Aurora PostgreSQL確認
aws rds describe-db-instances \
--db-instance-identifier aurora-prod-01 \
--query 'DBInstances[0].EngineVersion'
# 出力: 15.2
次に、Aurora側で Binary Logging を有効にする必要があります。デフォルトでは無効なので、パラメータグループを修正。
-- Aurora Parameter Groupで以下を設定
rds.logical_replication = 1
wal_level = logical
max_wal_senders = 15 -- デフォルトで大丈夫な場合が多い
log_bin_trust_function_creators = 1
この設定変更にはAuroraクラスタの再起動が必要で、うちは夜間メンテナンス窓で対応しました。20分程度で完了。
2. Redshift Provisioned Clusterの準備
Zero-ETL統合は Redshift Provisioned(ノードベース)クラスタと、Redshift Spectrum環境で使える Managed Storage を組み合わせて動作します。うちはアナリティクス用にServerless v2を使ってたんですが、実はServerlessでもZero-ETLは対応してるんですよね(2026年春時点)。
ただ、Managed Storageを使う場合はProvisioned Clusterが推奨なので、アナリティクスワークロードをProvisioned(dc2.large×3ノード)に切り替えることにしました。
正直、ここが一番大変だった。既存のクエリパフォーマンスを落とさずにノード数を最適化する必要があったから、2週間くらいベンチマーク取りまくってました。
3. Zero-ETL統合の作成
AWSコンソールから、またはAWS CLIで統合を作成します。
aws redshift create-integration \
--integration-name aurora-to-redshift-zero-etl \
--source-arn arn:aws:rds:ap-northeast-1:123456789:cluster:aurora-prod-01 \
--target-arn arn:aws:redshift:ap-northeast-1:123456789:cluster:analytics-prod
コンソールだと、Redshift → 管理 → 統合 → 新しい統合を選んで、AuroraクラスタとRedshiftクラスタを選択するだけ。簡単です。
重要なのは、このときどのスキーマを同期するかを指定できるってこと。うちはproduction スキーマだけを同期対象に指定して、テスト用のスキーマは別管理にしました。
4. 初期スナップショット実行
統合を作成するとAuroraのスナップショットが自動で取られ、それがRedshiftに全データとしてロードされます。うちの場合テーブルサイズが400GB程度だったから、約1.5時間で初期同期が完了。
初期同期の進行状況は、Redshiftコンソールの「統合」セクションで確認できます。
初期同期の流れ:
- Auroraスナップショット取得(10分)
- S3への一時アンロード(20分)
- Redshiftへのロード(70分) → 合計100分程度
本番運用してわかった、期待以上の結果
⚡ バッチ処理の消失
Zero-ETL統合が有効になった瞬間から、4時間のGlueジョブが全く必要なくなりました。
これまでは毎日21:00にGlueが起動して、01:00に完了するのを祈ってたんですが、今はデータがほぼリアルタイムに流れてくる。アナリティクスチームは朝8時に「昨日データがロード待ち」という状況から、いつでも直近データで分析できる環境に変わったんです。これだけで月間の分析サイクルが倍以上高速化した。
💰 運用コスト60%削減
Glueジョブの廃止により、Glueコンピュート費用が消滅。Lambda関数も不要に。かなり大きい。
| 項目 | 従来(月額) | Zero-ETL(月額) | 削減額 |
|---|---|---|---|
| Glue(DPU×24h × 30日) | ¥180,000 | ¥0 | ¥180,000 |
| Lambda(5回/日 × 30日) | ¥18,000 | ¥0 | ¥18,000 |
| 一時S3保存 | ¥8,000 | ¥0 | ¥8,000 |
| Aurora拡張(Binary Logging負荷) | ¥0 | ¥24,000 | -¥24,000 |
| Redshift Managed Storage | ¥0 | ¥48,000 | -¥48,000 |
| Redshiftクラスタ | ¥360,000 | ¥360,000 | ¥0 |
| 合計 | ¥566,000 | ¥432,000 | ¥134,000削減(65%) |
個人的には、このコスト削減より「Glueジョブの監視・トラブルシューティング」から解放されたことの方が、メンタル的に大きい。
🔄 スキーマ進化の自動追跡
これは予想外に便利でした。Auroraに新しいカラムを追加したら、Redshiftに自動で同じスキーマが生成されるんです。
これまでは、Glueジョブのカラムマッピングを手動で修正する必要があったから、スキーマ変更が「計画的な大事」だったんですよね。データチームに事前に連絡して、Glueの設定変更を待って…って流れがあった。それが単なる「追加」になったから、開発チームの自由度が一気に上がりました。
はまった落とし穴と対策
1. Redshiftの既存テーブルと競合する
Zero-ETL統合が作成するRedshift上のテーブル名は、Aurora側のテーブル名と全く同じになります。うちは既に分析用テーブルを手作業で作ってて、スキーマ名が競合しちゃった。
対策としては、統合作成前にRedshift上の既存テーブルを別スキーマに退避することですね。
-- Redshift側
CREATE SCHEMA analytics_old;
ALTER TABLE public.orders SET SCHEMA analytics_old;
ALTER TABLE public.users SET SCHEMA analytics_old;
2. 削除操作がRedshiftに反映される
Auroraでテーブルから行を削除すると、Redshiftの同じ行も削除されます。これは正しい動作なんですが、うちのチームは「Redshiftは過去全データの履歴」と思い込んでて、間違えてAuroraから大量削除した時点で本気で激怒されました。
GDPRの忘却権対応で削除が入ったのに、分析側のデータが消えちゃう状況が発生した。これ、結構痛い。
対策としては、削除前に分析用スナップショットを別テーブルに保存すること。具体的にはSCD Type 2(Slowly Changing Dimension)パターンを実装するのが定石。
-- Redshift側で定期的にSCD Type 2を実装
CREATE TABLE users_scd (
user_id INT,
name VARCHAR,
valid_from TIMESTAMP,
valid_to TIMESTAMP,
is_current BOOLEAN
);
3. Auroraの高負荷時にReplication Lagが発生
Binary Loggingを有効にすることで、Aurora側のwrite負荷が約8%増加しました。さらに、ピーク時間(夜21~23時)にはRedshiftへのレプリケーション遅延が数秒~数分出現するようになった。
うちはBatch処理が少なくなったから許容できましたが、リアルタイムダッシュボード要件のチームだと結構問題かもしれませんね。
対策としては、Aurora Readerを別のプロビジョニングに割き当てることです。
aws rds create-db-instance \
--db-instance-identifier aurora-reader-isolated \
--db-cluster-identifier aurora-prod-01 \
--instance-class db.r6i.xlarge
これでレプリケーション用とアプリケーション用のリーダーを分離できます。
4. Redshift側のストレージ容量を過小評価
Managed Storageは「無制限」という触れ込みですが、実際には課金が増えるだけで、パフォーマンス低下の可能性があります。うちは400GBのデータがAuroraからきたのに対して、Redshiftでは600GB消費してました。圧縮率の違いだろうけど、想定外でした。
対策としては、最初の1ヶ月は容量監視を毎日確認することですね。
-- Redshift Managed Storage使用量確認
SELECT
SUM(total_rows) * AVG(approx_record_size) / 1024 / 1024 / 1024 as size_gb
FROM svv_diskusage;
AWS構成図:うちの本番環境
graph TB
subgraph aurora ["Aurora PostgreSQL (ap-northeast-1a/1c)"]
aurora_writer[("Primary Instance<br/>db.r6i.2xlarge")]
aurora_reader[("Reader Instance<br/>db.r6i.xlarge<br/>レプリケーション専用")]
aurora_writer -->|Binary Logging<br/>WAL| aurora_reader
end
subgraph zero_etl ["Zero-ETL Integration"]
integration["Aurora → Redshift<br/>リアルタイム同期"]
end
subgraph redshift ["Redshift (ap-northeast-1a)"]
redshift_cluster["Provisioned Cluster<br/>dc2.large × 3 nodes<br/>128GB/node"]
managed_storage[("Managed Storage<br/>PA3 RA3 Nodes")]
redshift_cluster -->|Auto Scaling| managed_storage
end
subgraph analytics ["Analytics Layer"]
metabase["Metabase<br/>BI Dashboard"]
dbt["dbt Transformations<br/>マートテーブル生成"]
end
aurora_reader -->|Initial Snapshot<br/>+ CDC| integration
integration -->|Upsert/Delete<br/>リアルタイム| redshift_cluster
redshift_cluster -->|SELECT| metabase
redshift_cluster -->|dbt run| dbt
dbt -->|INSERT INTO| redshift_cluster
style aurora fill:#FF9900
style redshift fill:#527FFF
style managed_storage fill:#146EB4
style integration fill:#EC7211
この構成で月間60%のコスト削減と、データ遅延の大幅短縮を実現できました。
2026年のZero-ETL、さらに使える機能
最近のアップデートでいくつか便利になったことがあります。
複数スキーマの同時同期
初期は1つの統合=1つのスキーマでしたが、今は1つの統合で複数スキーマを指定可能。うちでも本番・ステージング・分析用と3つのスキーマを管理してますが、統合は1つで済みます。これだけで管理負荷が減った。
Redshiftのコンピュートノードスケーリング
Zero-ETLのレプリケーション負荷に応じて、Redshiftの自動スケーリング戦略が改善されました。ピーク時の遅延をほぼ0に抑えられるようになった。
IAMロールベースのアクセス制御
統合自体に対するIAMポリシーがより細かく制御できるようになり、SOC2対応も楽になりました。セキュリティチームも満足。
正直に言うと、これからやるなら
まず間違いなく最初からZero-ETLを選ぶと思います。ただし、いくつか条件がありますね。
削除操作への対応が必須
GDPRとか個人情報削除要件があるなら、アナリティクス側の履歴保持戦略を先に決める必要があります。後付けするとめんどい。
Auroraの負荷増加を許容できるか
write負荷が既に高いなら、リーダーインスタンスの追加を検討した方がいい。8%の負荷増加は、スケールしてないシステムではそこそこ大きい。
スキーマ進化の頻度
頻繁にカラム追加があるなら本当に楽。ただし、カラムを削除する場合は手動対応が必要になることが多いから、その辺り覚悟しておいた方がいい。
リアルタイム性の要件
秒単位の遅延が許容できるなら最高。でも数時間単位の遅延でいいなら、従来のETLのほうがシンプルで、トラブルも少ないと思いますよ。
うちのチームでは3ヶ月運用してから本当に定着して、今ではこれなしには動けない体になってしまいました。
まとめ
- Zero-ETL統合はAuroraのバージョン14.6以降で対応。Binary Loggingの有効化が必須だが、再起動は最小限で済む
- Glue・Lambdaが不要になるので、月間60~70%のコスト削減が見込める。ただし初期設定とスキーマ競合への対応は必要
- リアルタイム化により、バッチ待ちが消滅。分析チームの生産性が倍以上に向上する
- 削除操作や高負荷時のlag対策は、事前設計が重要。特にGDPR対応とAuroraリーダーの構成は必ず検討を
- 既存ETLからの移行は段階的に。新規テーブルから始めて、既存テーブルは1つずつ切り替えるくらいの慎重さで十分
2026年時点ではかなり安定した機能になってるので、Auroraを使ってるなら一度トライアルでテストテーブルから始めてみる価値はありますよ。実装の手軽さと効果は、本当に期待値を超えると思います。