Aurora→Redshift間のZero-ETL統合を本番導入してわかったこと|3ヶ月で60%高速化した実装記

毎晩3時間かかってたバッチ処理がZero-ETL統合で秒単位に。Lambda地獄から解放された実装記。実際にやってみて気づいた落とし穴と運用のコツを赤裸々に。

従来のETL地獄から解放された日

先日、うちのチームが抱えていた深刻な問題がようやく解決した。毎晩22時に開始するデータパイプラインで、AuroraからRedshiftにデータを吸い上げるバッチ処理が走るんだけど、データ量の増加に伴って処理時間が3時間まで膨れ上がってた。その間、アナリティクスチームは古いデータで分析をしてるし、朝の経営会議の直前にようやく最新データが反映される…みたいな悪循環だった。

去年まではLambda+Glueで無理やり回してたんだけど、保守がマジでしんどかった。パイプラインが落ちるたびに夜中に呼び出されるし、スケーリングの調整も毎月必要で、本当にやめたかった。そこで2026年にようやく広く使えるようになったZero-ETL統合を試してみたら、これが想像以上に便利だった。

Zero-ETL統合って何が変わるのか

正直に言うと、最初は「何が新しいのか」ピンと来なかった。だけど実装してみると、その威力がわかるんだ。従来のバッチ処理では、AuroraのテーブルをS3経由で加工・ロードする必要があった。もしくはLambdaでデータを抽出して、Redshiftに突っ込む。その間、どうしても遅延が生まれるわけだ。

Zero-ETL統合の場合、AuroraがRedshiftに自動的にデータを同期する。Auroraへの書き込みと並行してRedshiftが更新されるから、データベースレベルの遅延でしか差が出ない。つまり、ほぼリアルタイムでウェアハウス側が最新のデータを持つようになる。

うちのチームが導入する前、正直な感想は「こんなのほぼ魔法では?」だった。でも実装の詳細を調べると、Auroraの変更データキャプチャ(CDC)機能とRedshiftのダイレクト統合を使ってるんだ。つまり、きちんとしたテクノロジーの上に成り立ってる。

従来のパイプライン (遅延3時間)
Aurora → Lambda抽出 → S3 → Glueジョブ → Redshift
            ↑         ↑      ↑
          エラーやすい バッチ待ち 複雑な設定

Zero-ETL統合 (遅延秒単位)
Aurora ===CDC=== Redshift
  ↑               ↑
リアルタイム    リアルタイム

実装してわかった、地味だけど重い落とし穴

もちろん導入は簡単じゃなかった。AWS CloudFormationで統合を作るのは数分で終わるんだけど、その後の調整がめんどくさい。

テーブルスキーマの事前準備が意外と重い

Zero-ETL統合を有効にする前に、Redshift側にテーブルを作成しておく必要がある。Auroraのスキーマをそのままコピーできると思ってたんだけど、そうじゃなかった。AuroraのJSON型やUUID型が、Redshiftではそのまま対応してない場合があるんだ。

うちは本番前のテスト環境で気づいたから良かったけど、本番いきなりやってたら「え、データ型エラーなん?」ってなってた。結局、Auroraの全テーブルをDESCRIBEして、Redshiftの型に合わせてCREATE TABLE文を手書きする羽目になった。

Aurora側のデータ型Redshift互換型注意点
UUIDVARCHAR(36)バイナリ型のまま移行不可
JSONBVARCHAR(MAX)データ量が大きい場合は圧縮推奨
TIMESTAMP WITH TIME ZONETIMESTAMPタイムゾーン情報は失われる
INTEGER ARRAYVARCHAR(MAX)配列型をJSON文字列に変換

正直、この部分が文書化されてない。AWSのドキュメントを読んでも「型を合わせてください」とだけ書いてある。実務的には、DMS(Database Migration Service)のスキーマ変換機能を使うか、自分たちで互換性チェックツールを作った方が楽かもしれない。

ネットワーク設定がめんどくさい

AuroraとRedshiftが同じVPC内にある場合はいいんだけど、違うVPCにある場合、エンドポイント設定がいる。うちは段階的にマイグレーションしてて、本番のAuroraと検証用のRedshiftが別VPCにあった。

PrivateLinkを使った統合も試したんだけど、設定ミスがあると「接続タイムアウト」で黙ってデータが流れない。エラーログもはっきり出ないから、CloudWatch Logs を掘り返して「あ、security groupが塞がってたのか」って気づく始末。

実装のときは、必ずセキュリティグループとネットワークACLを両方チェックすること。そして接続テストで小さなテーブルから始めること。本番のメインテーブルでいきなり試すと、10GB のデータが半端な状態で同期されて、ロールバックが地獄になるんだ。

データ品質の監視が新しい課題になる

バッチ処理だと、パイプラインの成功・失敗が明確だった。Glueジョブが成功したら「データ反映完了」。失敗したら「データ古い」。シンプルだったんだ。

Zero-ETL統合は、常に同期し続けるから、部分的な遅延が発生しうる。例えば、Auroraの大型トランザクションがロック中だと、Redshift側の同期が止まる。でも「同期失敗」というわけじゃないから、黙ってデータの鮮度が落ちてく。

うちのチームは3週間目に気づいた。分析チームから「あ、この数字おかしくね?」という指摘を受けて。原因は、Aurora の大型バッチジョブ(夜間インデックス再構築)で、CDC の遅延が発生してたんだ。

対策として、うちは CloudWatch メトリクスを設定した。

# Python + boto3で同期遅延を監視
import boto3
from datetime import datetime, timedelta

redshift = boto3.client('redshift-data')

def check_sync_lag():
    # Redshiftの最新レコード更新時刻を取得
    response = redshift.execute_statement(
        ClusterIdentifier='analytics-cluster',
        Database='analytics_db',
        Sql='''
            SELECT MAX(updated_at) as latest_update
            FROM transactions
        '''
    )
    
    latest = response['Records'][0]['updated_at']['value']
    current_time = datetime.utcnow()
    lag = (current_time - latest).total_seconds()
    
    # 遅延が5分以上なら警告
    if lag > 300:
        send_alert(f"Sync lag: {lag} seconds")
    
    return lag

実装コード的には簡単だけど、「何を監視すべきか」という設計が大事。バッチのように「最後の実行時刻」だけじゃなく、テーブルごとの鮮度を追跡する必要があるんだ。

パフォーマンス検証の結果

Zero-ETL統合を導入して3ヶ月。実際のデータで検証した結果がこれだ。

xychart-beta
    title ウェアハウスへのデータ反映遅延
    x-axis [Glue方式, Lambda方式, Zero-ETL統合]
    y-axis "遅延時間(分)" 0 180
    line [165, 95, 2.3]

Glue方式のときは平均165分の遅延。Lambda方式にしたときでも95分。でもZero-ETL統合は平均2.3分。ほぼリアルタイムだ。

コスト的にも、バッチジョブの実行回数が激減したから、Compute Unit の使用料が月30万円から月8万円に下がった。

xychart-beta
    title 月額 Redshift コスト比較
    x-axis [2025年6月, 7月, 8月, 2026年1月, 2月, 3月]
    y-axis "コスト(万円)" 0 50
    line [32, 31, 30, 8.5, 8.2, 8.8]

正直、ここまで削減できるとは思わなかった。バッチが走ってない時間帯のコンピュートを完全に削減できたのが大きい。

AWS構成図:Zero-ETL統合の実装

graph TB
    subgraph "Production VPC"
        Aurora["Aurora PostgreSQL<br/>(Source DB)"]
        AuroraReplica["Aurora Replica<br/>(CDC Source)"]
        
        Aurora -->|Binary Logs| AuroraReplica
    end
    
    subgraph "Analytics VPC"
        Redshift["Redshift Data Warehouse<br/>(Analysis Ready)"]
    end
    
    subgraph "Zero-ETL Integration"
        CDCEngine["Change Data Capture<br/>(Real-time)"]
        SyncService["Continuous Sync Service"]
    end
    
    AuroraReplica -->|CDC Stream| CDCEngine
    CDCEngine -->|Transform| SyncService
    SyncService -->|Direct Load| Redshift
    
    subgraph "Monitoring & Control"
        CloudWatch["CloudWatch Metrics<br/>(Sync Lag)"]
        EventBridge["EventBridge<br/>(Alerts)"]
    end
    
    SyncService -->|Metrics| CloudWatch
    CloudWatch -->|Triggers| EventBridge
    
    style Aurora fill:#FF9800
    style Redshift fill:#4CAF50
    style CDCEngine fill:#2196F3
    style CloudWatch fill:#FFC107

重要なポイントが3つある。

1. Auroraレプリカの役割 — Zero-ETL統合はレプリカから変更を読み取る。マスターへの負荷を避けるため、専用レプリカを用意するのがベストプラクティス。

2. PrivateLink経由の接続 — VPC間の通信はPrivateLinkで安全に。データは一切インターネットを経由しない。

3. CloudWatch監視 — 同期遅延をリアルタイム監視。5分以上の遅延で自動アラート。

本番運用で学んだこと

大規模トランザクションはAuroraで事前テスト

月次集計ジョブみたいな大型トランザクションを走らせるときは、必ずAuroraで事前実行して、Redshiftへの同期遅延をテストした。一度、深夜の在庫更新バッチ(テーブル全体をロック)で、Redshiftの遅延が15分になって、朝の経営会議で古いデータが表示される事態が発生したんだ。

対策として、大型更新は時間帯を分散させるか、バッチサイズを小さくすることに。Zero-ETLはリアルタイムだからこそ、Auroraの負荷が直接Redshiftに影響する。

スキーマ変更のタイミングが重要

Auroraでカラムを追加すると、Redshiftに自動反映されない。スキーマ変更は手動でRedshift側も実行する必要がある。その間、データは古い構造で流れ続けるんだ。

うちは ALTER TABLE の順序を決めた。Auroraで先行してカラムを追加(DEFAULT値付き)→ 翌日の深夜メンテナンスウィンドウでRedshift更新。このタイミングを間違うと、アプリケーションエラーになる。

権限管理がAuroraとRedshiftで別

Zero-ETL統合を作成するには、IAM ロール(AWSDataExchangeFullAccess相当)が必要。でもテーブル単位のアクセス制御は、Auroraとredshiftそれぞれで設定しないといけない。Auroraで SELECT権限があっても、Redshiftで権限がないと見えない。

最初、アナリティクスチーム全員が「テーブルが見えない」って言ってきたから、権限系の設定を全部チェックし直した。ドキュメント不足の領域だから、実装時は念入りにテストが必要なんだ。

次のステップと課題

Zero-ETL統合は素晴らしいテクノロジーだけど、やっぱり新しいから、落とし穴もある。

うちのチームは今、マルチテーブルの整合性を考えてる。複数のテーブルに関連データがあるとき、Auroraでは1つのトランザクション内で更新されるけど、Redshiftへの同期は別々に走る。つまり、ほんの短い間だけ、Redshiftのデータが不整合になる可能性があるんだ。

分析用途なら大抵問題ないんだけど、金融データや在庫データみたいにシビアな場合は注意が必要。

もう一つの課題は、トランザクション境界の尊重。Aurora の UPDATE が複数行に渡るとき、Redshift 側で部分的に反映される。これを完全に防ぐのは現状難しい。

# Auroraでの実行
BEGIN TRANSACTION;
  UPDATE accounts SET balance = balance - 100 WHERE id = 1;
  UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;

# Redshiftへの同期(2つの UPDATE が別のタイミングで到着する可能性)
# → 一瞬、合計残高が変わることもある

この部分はAWSも改善中らしいけど、2026年2月時点ではまだ。うちは分析目的だからトレランスしてるけど、オペレーショナルなユースケースだったら別のアプローチを検討する必要がある。

似たサービスとの比較

Zero-ETL統合が出る前は、DMS(Database Migration Service)やLambda + EventBridgeで無理やりリアルタイムパイプラインを作ってた。個人的に思うのは、Zero-ETL統合が圧倒的に優れてるってことだ。

観点DMSLambda + EventBridgeZero-ETL統合
セットアップ時間数時間数日30分
ランニングコスト高い(インスタンス費用)中程度(計算費)低い(データ転送のみ)
遅延秒〜分分〜時間秒〜数秒
スキーマ変更対応手動で反映自分で実装手動で反映
保守負荷中程度高い低い
エラーハンドリングAWS側で対応自分で実装AWS側で対応

既存のDMS環境がある場合、無理に乗り換える必要はないと思う。ただ、新規構築なら絶対Zero-ETL統合を選ぶ。それくらい楽だ。

まとめ

Aurora → Redshift の Zero-ETL統合は、リアルタイムデータウェアハウスの運用を劇的に改善する。うちのチームは導入後、データ遅延が165分から2.3分に短縮され、月額コストも月30万円から月8万円に削減できた。

実装時の注意点は3つだ。

1. テーブルスキーマの事前検証 — AuroraとRedshiftの型互換性を確認しておく。DMS のスキーマ変換機能が便利。

2. ネットワーク設定とセキュリティグループ — VPC間通信はPrivateLink で、security group の設定ミスで黙ってデータが流れなくなる。

3. 同期遅延の監視体制 — バッチと違い、失敗がわかりにくい。CloudWatch メトリクスで常に監視し、5分以上の遅延で即座にアラートが来る仕組みを作る。

大型トランザクションやスキーマ変更のタイミングには気をつけること。そして、金融・在庫など整合性が命の場面では、トランザクション境界の細かい挙動を理解した上で導入すること。

正直、2025年までは「Zero-ETL って名前だけで実用的じゃない」と思ってた。でも2026年時点で、こんなに安定して動いてるなら、新規でAuroraとRedshiftを組み合わせるケースはほぼ全部これ使うべき。バッチ処理の地獄からようやく解放されたんだ。

U

Untanbaby

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

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

関連記事