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 → RedshiftAurora → 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コンソールの「統合」セクションで確認できます。

初期同期の流れ:

  1. Auroraスナップショット取得(10分)
  2. S3への一時アンロード(20分)
  3. 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を使ってるなら一度トライアルでテストテーブルから始めてみる価値はありますよ。実装の手軽さと効果は、本当に期待値を超えると思います。

U

Untanbaby

ソフトウェアエンジニア|AWS / クラウドアーキテクチャ / DevOps

10年以上のIT実務経験をもとに、現場で使える技術情報を発信しています。 記事の誤りや改善点があればお問い合わせからお気軽にご連絡ください。

関連記事