
さとうです。
最近データ基盤のOLAPとOLTPについて考えることが増えてきたので記事にしました。
趣旨はタイトル通り、「OLTPデータベースをデータ基盤に取り込むためにはどうしたらいいか?」という課題に対する設計パターンのまとめです。
OLTPとOLAPについて
概要
OLTP/OLAPとは、データベースにおける処理特性のことを指します。
以後、記載を簡略にするため単にOLTP/OLAPと呼ぶ場合はその処理に特化したデータベース自体のことを指すものと思ってください。
OLTP (Online Transaction Processing)
アプリケーションのバックエンドとしてミリ秒単位の細かい読み書き(CRUD)を大量かつ並行して処理するための処理です。データの整合性(ACID特性)が最優先されます。行指向で保存されるため、会員情報の索引など行単位の処理が得意です。
AWSの場合、Amazon AuroraやRDSなどのサービスが該当します。
OLAP (Online Analytical Processing)
大量のデータを集計・分析するための処理です。トランザクション処理には不向きですが、列指向で保存されるため、カラムの集計やテーブルの結合処理など列単位の処理が得意です。
AWSの場合、Amazon RedshiftやAmazon S3 Tables(Apache Iceberg)などのサービスが該当します。
データ基盤にOLTPを統合したい動機
伝統的なデータ基盤はOLAPデータベースを前提とした構成でした。業務システム(OLTP)のデータは夜間バッチで日次抽出され、DWH(OLAP)にロードされてから分析されるのが一般的でした。定型的なダッシュボード作成などのパーソナライズ不要なデータの提供や、分析者向けの分析環境の提供など少人数向けの用途では有用な構成です。
しかし、最近は「AIエージェントがユーザーの最新の購買履歴を参照してレコメンドを返す」「データマートをAPIから参照できるようにコンシューマ向けアプリと連携したい」といった要件の相談を頂くことが増えています。こういったデータの民主化(誰でもデータを使える状態)が進むと、パーソナライズされたデータの提供や不特定多数への分析環境の提供などOLTPの特性が必要となるユースケースが増えるのです。

OLAPとOLTPの処理性能の比較
では、OLAPがOLTP的なトラフィックを処理するとどうなるのでしょうか?
以前、下記の記事でAmazon S3 TablesとAmazon Auroraの読み書き性能のパフォーマンス測定をして比較しました。
こちらの通りAmazon S3 Tablesの読み込み処理は同時リクエスト数に比例して最大でAmazon Auroraの約16倍遅くなり、レスポンスにも最大で2秒以上要する結果になっています。OLAPがOLTP的な同時接続処理を捌くことが苦手であることは明白です。
また、Amazon Redshift Data API と Amazon RDS Data API のクォータを比較しても同様の傾向が見て取れます。
Amazon Redshift でのクォータと制限 - Amazon Redshift
Amazon RDS Data API の制限 - Amazon Aurora
任意のSQLを実行するExecuteStatementのクォータがAmazon Redshift Data APIでは30リクエスト/秒であるのに対して、Amazon RDS Data APIでは1000回/秒(Aurora Serverless v1の場合)または制限なし(その他の場合)と大きな差があります。
OLTPを統合する場合の課題
OLTPをデータ基盤に統合するという発想はここ数年のトレンドですが、それだけに課題も多いです。
OLTPとOLAPの同期
OLTPとOLAPで同じデータを取り扱いたい場合、データの整合性をどのように保証するかがポイントになります。
バッチ処理による全量の洗い替えはデータ量が増えると破綻する可能性があり、テーブル構成の変更が生じると処理ロジックが壊れる(スキーマドリフト)という問題も考えられます。理想としてはOLTPかOLAPのどちらかを正とし、継続的なデータ同期とスキーマ追跡(スキーマの変動を自動的に反映する)ができる処理を実装することが望ましいです。
データカタログの統合管理
AIエージェントの普及に伴い、データの在処とドメイン知識を集約してコンテキストとして活用するためにデータカタログの重要性が高まっています。
OLTPとOLAPで提供されるデータをカタログとして一括提供することで、AWS Lake Formationと組み合わせた権限管理の一元化などメリットも享受することができます。
設計原則
どのような設計原則でOLTPを統合すべきか、重要なポイントをまとめます。
データベースの分離
それぞれのユースケースがサービスに負荷を与えることを避けるため、OLTPとOLAPで必ずデータベースを分離するようにしてください。
OLTPに対して直接重い集計クエリを実行させる、OLAPに対して大量のリクエストを送信するなどの本来想定されていない利用は、データベースの処理負荷により共倒れになるリスクがあります。
SSOT(信頼できる唯一の情報源)を決める
OLTPもしくはOLAPのいずれかを正とし、もう一方はデータの同期のみを受け付けることで整合性を確保します。
例えばOLAPを正とする場合、基本的にOLTPはOLAPのリードレプリカとして振る舞うように設計する必要があります。書き込みリクエストを受け付けてはいけません。
ETLジョブはリトライ可能な疎結合構成にする
OLTPとOLAPはそれぞれ別のデータベースであるため、トランザクションを一元化することはできません。そのため、ACID特性を守ることが難しくなります。
OLTPとOLAP間の処理をACIDにするため、疎結合なETLジョブの設計が重要となります。
例えばOLAP側のデータ反映は正常に完了したものの、OLTPに同じデータを同期する処理が失敗したとします。この場合、OLAPとOLTPでデータの不整合が発生します。
リカバリにはOLTP側のジョブの再実行が必要となりますが、OLAP側の処理とOLTP側の処理が密結合になっているとこのような部分的なリトライ処理ができなくなります。
そのため、リトライを考慮したジョブの親子付けなど疎結合なジョブの構成が重要となります。
設計パターン
前提

図のようにAWSへのデータソースの集約とクレンジング処理は終わっていることを前提に、OLTPを統合するための構成の例を示します。
以下を前提条件とします。
- メダリオンアーキテクチャを前提に、Bronze(生データ)、Silver(クレンジング済データ)、Gold(データマート)に分類される
- Bronze/Silver相当のデータはAWS上のOLAPまたはOLTPに既に集約されているものとする
- Gold相当のデータはOLTPとOLAPで同一のデータを持つように整合性を確保する
OLAPおよびOLTPには以下のデータベースを利用することを前提に考えます。
- OLTP: Amazon Aurora PostgreSQL 16.4
- OLAP: Amazon Redshift ServerlessまたはAmazon S3 Tables
OLTPを正としてOLAPを拡張するZero ETL統合パターン
概要


※図は以下より引用
Aurora ゼロ ETL 統合 - Amazon Aurora
Amazon AuroraのZero ETL統合を活用してOLTP→OLAPにシームレスにデータを同期する方法です。業務データをOLAPに取り込むETL処理を簡略化することを目的とした機能ですが、やっていることはテーブル同期なのでこのような用途にも応用できます。
| From | To | 同期タイミング | スキーマ追跡 | 技術スタック |
|---|---|---|---|---|
| Amazon Aurora | Amazon Redshift | リアルタイム | 可 | SQL |
| Amazon Aurora | Amazon Sagemaker Lakehouse | リアルタイム | 可 | SQL |
向いている/向いていないケース
OLTPデータベースでも処理しきれるシンプルな処理(データ処理がGB単位、ETLの加工ロジックが比較的単純)が想定される小規模なデータ基盤に向いています。
このパターンを採用するメリットは設定が容易という1点に集約されると思います。どちらもスキーマ追従まで行ってくれるためETLの開発コストは名前通りほぼゼロです。
一方でAmazon Auroraは行指向データベースであり、OLAPのような複雑な計算処理には明確に不向きです。年間を通してGB単位のデータ処理であればAuroraだけでもデータ基盤として成立させることは可能ですが、TB単位のデータ処理を前提とした構成とする場合にはデータベース特性が技術負債になることが想定されます。Aurora Servelessであれば柔軟にスケールアップは可能ですが、マシンスペックを上げること自体は根本的な解決にはなりません。
Amazon RedshiftにZero ETL統合する場合

仕組み
Amazon AuroraからAmazon Redshiftに統合するパターンです。読み取り専用でデータを同期します。
制約として、連携先のAmazon RedshiftはServerlessまたはプロビジョン済クラスターのRA3インスタンス(マルチノード)であるほか、暗号化が有効になっている必要があります。Redshift Managed Storage(RMS)に依存した統合であるためと思われます。
実装方法
- 送信元のAurora AuroraクラスターでZero ETL統合用のパラメータグループを作成して関連付ける
- 統合先のAmazon Redshiftで大文字と小文字の区別を有効にする
- 統合先のAmazon Redshiftで承認済の統合ソースとして設定する
- Zero ETL統合を送信元のAmazon Auroraクラスターで設定する
Aurora ゼロ ETL 統合の開始方法 - Amazon Aurora
Amazon Redshift との Amazon ゼロ ETL 統合の作成 - Amazon Aurora
Amazon Sagemaker LakehouseにZero ETL統合する場合

仕組み
AWS Lake FormationにAmazon Redshift マネージドカタログを作成することで、その裏に自動的にRedshift Managed Workgroup(AWSが管理するAmazon Redshift Serverlessのワークグループ)が作成され、マネージドカタログ経由でApache Iceberg REST API を使ってZero ETL統合したテーブルに読み取り専用でアクセスできるというものです。
単純なRedshiftとの統合と比べると非常に複雑ですが、やっていることはAmazon Redshiftを隠蔽しているだけで基本的な仕組みは同じです。AWS Lake Formationによる権限管理やApache Icebergのクエリエンジン経由のアクセスなど、Amazon Sagemaker Lakehouseからシームレスに利用ができるように統合されています。
Apache Iceberg の Amazon Redshift との互換性 - Amazon Redshift
実装方法
方法も複雑です。下記2つのドキュメントを行ったり来たりしますが、おおよそ以下の流れで設定します。
- 送信元のAurora AuroraクラスターでZero ETL統合用のパラメータグループを作成して関連付ける
- サービスリンクロール
AWSServiceRoleForRedshiftを作成する ※Amazon Redshiftを一度も利用したことがない場合 - AWS Lake Formationで
AWSServiceRoleForRedshiftを読み取り専用の管理者として登録する - Amazon Redshift マネージドカタログ用のIAMロールを作成する
- AWS Lake FormationでAmazon Redshift マネージドカタログを作成する
- GlueData CatalogでZero ETL統合を設定するAuroraクラスターからのインバウンド統合を許可するポリシーを設定する
- Zero ETL統合用のIAMロールを作成する
- Zero ETL統合を送信元のAmazon Auroraクラスターで設定する
Aurora ゼロ ETL 統合の開始方法 - Amazon Aurora
Amazon SageMaker Lakehouse との Aurora ゼロ ETL 統合の作成 - Amazon Aurora
OLAPを正としてOLTPを拡張するリバースETLパターン
概要


リバースETLとは、名前通りデータ基盤から別のデータソースに対するETL処理を指します。ここではOLAP→OLTPへのデータ同期のプロセスをリバースETLと呼びます。バルクインポートする方式とJDBCで直接書き込む方式の2通りが考えられます。
| 方式 | From | To | 同期タイミング | スキーマ追跡 | 技術スタック |
|---|---|---|---|---|---|
| バルク | Amazon Redshift | Amazon Aurora | バッチ処理 | 不可 | SQL |
| バルク | Amazon S3 Tables | Amazon Aurora | バッチ処理 | 不可 | SQL |
| JDBC | Amazon Redshift | Amazon Aurora | バッチ処理 | 可(ロジック次第) | Python(PySpark)/SQL |
| JDBC | Amazon S3 Tables | Amazon Aurora | バッチ処理 | 可(ロジック次第) | Python(PySpark)/SQL |
向いている/向いていないケース
従来型のOLAP型のデータ基盤にOLTPを拡充するため、既存のデータ基盤からの拡張が容易というメリットがあります。既存資源を活用してOLTP向けデータベースを拡張するといった実装に向いています。また、データ量がTB規模であるかETLプロセスに複雑な計算処理を含むなど、ETL処理をOLTPで行うことが難しい場合はこの方式を検討します。
向いていないケースはありませんが、同期ロジックはパフォーマンスを考慮して自分で実装する必要があります。例えば単純な洗替処理はシンプルな処理ですが、データが大容量になるとオーバーヘッドが非常に大きくなるため全てには採用できません。変更データだけを差分として抽出して反映する方式にするとオーバーヘッドは小さくなりますが、ロジックに不備があるとデータの不整合が起きるリスクがあります。
バルクインポートする場合
仕組み

Amazon RedshiftかAmazon Athenaを使ってAmazon S3にデータをアンロードした上でAmazon Aurora標準のインポート機能を使って取り込みます。
イメージとしては①アンロードするジョブ、②ステージングテーブルにインポートするジョブ、③ステージングテーブルから本番テーブルに反映する処理、を疎結合にして各処理をリトライ可能にします。ジョブの実装手段は図のようにAWS Step Step Functionsである必要はありませんが、ジョブの親子付けができることが重要です。詳細は以前執筆した以下の記事を参考にしてください。
メリットは処理ロジックがシンプルなことで、データ量の少ないマスタデータを都度洗替する場合や、差分がレコードの増量のみでINSERTするだけでよいなどシンプルな同期をする方法に向いています。
一方でスキーマ追跡には対応していないため、OLTP側で手動でスキーマの修正が必要になるなどのデメリットも存在します。
実装方法
以下の組み込みのSQL関数を利用し、SQLの実行をワークフローとして組み合わせます。
以前執筆したAWS Step Functionsの使い方を基礎から解説した記事も添付しました。ETLジョブの組み立てにも応用することができるのでこちらも参考にしてください。
Amazon S3 から Aurora PostgreSQL DB クラスター にデータをインポートする - Amazon Aurora
Amazon S3 バケットのテキストファイルから Amazon Aurora MySQL DB クラスターへのデータのロード - Amazon Aurora
JDBCで直接書き込む場合
仕組み

AWS Glue(PySpark)を使ってOLAPとOLTPの間の同期処理を反映する方法です。
Amazon RedshiftとAmazon S3 Tablesはネイティブで接続がサポートされているほか、Amazon AuroraにはJDBCで接続することができます。
AWS Glue を使用した Amazon S3 テーブルでの ETL ジョブの実行 - Amazon Simple Storage Service
OLAPとOLTPのデータをDataFrameとしてAWS Glueのメモリ上に保存するため、バルクインポート方式のようにファイルへの書き込みが発生しません。原始性(成功か失敗か)を保ちつつスクリプトで同期処理を冪等にすることができます。
PySparkはSQLを実行できることはもちろん、DataFrame同士の差分比較などの強力な関数が揃っています。実装次第でスキーマの変動を検知してAmazon Aurora側のDDLを変更するなど自由度の高い処理を組むことができるのが特徴です。
実装方法
基本的にはバルクインポート方式と同様です。
PySpark で AWS Glue ETL スクリプトをプログラムする - AWS Glue
まとめ
OLAPとOLTPをデータ基盤に統合する方法をまとめました。
どなたかの参考になれば幸いです。
佐藤 航太郎(執筆記事の一覧)
クロスインダストリー第1本部 クラウドモダナイズ課
最近はデータエンジニアのようなことをしています。