RDSレプリケーションの同期、非同期についてまとめました

RDSのレプリケーション（ソースレプリカとデータが同じレプリカを用意すること）には同期、非同期があるのですが、パターンが多すぎてどれがどっちか分からん！！


ということでまとめました。

# 前提
2023/6/15時点の情報になります。
AWSは日々システムが更新されるので公式ドキュメントの確認は必須。

# 結論
#### Aurora以外のRDS
　・マルチAZ配置:同期レプリケーション
　・マルチAZ DBクラスター：準同期レプリケーション
　・リードレプリカ：非同期レプリケーション

#### Aurora
　同期レプリケーションと呼ばない方が良い。（ボリュームの共有）


# そもそも同期レプリケーションの定義とは？
> RDSのMultiAZは、データベースの障害時の影響を最小化するために同期レプリケーションを行っています。これは、マスターへの変更の後にスレーブを変更し確定してから応答します。
よって、マスターとスレーブ間の通信の分だけ遅くなってしまいますが、RDSは、データセンター間を高速な回線で繋ぐことで数msの遅延と非常に高速です。
ちなみに、非同期レプリケーションは、スレーブへの書き込み完了を待たずに応答します。ということで、RDSは、MultiAZ構成において同期レプリケーションを行っています。

つまり
同期→レプリケーションが完了するのを待つ
非同期→レプリケーション完了を待たずに、次の処理（クエリ等）を受け付ける

どいうことです。

> 参考：[Amazon RDSによるレプリケーションについて理解する](https://dev.classmethod.jp/articles/amazon-rds-replication/)


# 1. RDS (Aurora以外)
## (1) スタンバイレプリカ(マルチAZ配置）
### **同期** 

> Amazon RDS マルチ AZ 配置では、Amazon RDS はプライマリデータベース (DB) インスタンスを自動的に作成し、データを別の AZ のインスタンスに同期的にレプリケートします。
参考：[Amazon RDS マルチ AZ](https://aws.amazon.com/jp/rds/features/multi-az/)

## (2) リードレプリカ 
### **非同期** （秒単位）
> MySQL、MariaDB、PostgreSQL、Oracle、SQL Server のデータベースエンジンの場合、Amazon RDS ではソース DB インスタンスのスナップショットを使用して、2 番目の DB インスタンスを作成します。その後、ソース DB インスタンスが変更されるたびに、エンジンのネイティブ非同期レプリケーションを使用して、リードレプリカを更新します。
参考: [Amazon RDS リードレプリカ](https://aws.amazon.com/jp/rds/features/read-replicas/)



## (3) マルチAZ DBクラスター(読み取り可能な２つのスタンバイレプリカをもつ）
### 準同期（または半同期）
３つの異なるAZに一つのプライマリレプリカ＋２つの読み取り可能なスタンバイ(リード）レプリカが作られる設定になります。
> 3 個中 2 個の書き込みクォーラムを使用します
参考：[Amazon RDS マルチ AZ](https://aws.amazon.com/jp/rds/features/multi-az/)

→つまり、３個中２個（マスター＋レプリカ1個）に書き込みが完了していればOK＝**レプリカ1個同期、1個非同期**です。

> 参考：[マルチ AZ DB クラスターのデプロイメント](https://docs.aws.amazon.com/AmazonRDS/latest/UserGuide/multi-az-db-clusters-concepts-connection-management.html)


# 2. Aurora

## (1) リードレプリカ（同一リージョン）

### 同期レプリケーション（ミリ秒単位：10-20ms程度のレプリケーション遅延）

> Amazon Aurora レプリカはソースインスタンスと同じ基盤となるストレージを共有するので、コストが抑えられ、データをレプリカノードにコピーする必要がありません。
参考: [Amazon RDS リードレプリカ](https://aws.amazon.com/jp/rds/features/read-replicas/)
参考: [Amazon Aurora のよくある質問
](https://aws.amazon.com/jp/rds/aurora/faqs/#High_Availability_and_Replication)

が、Auroraはクォーラムモデルを採用しており、6個中4個の書き込みでオペレーション成功とみなします。
つまり、**4個同期、2個は非同期**です。

ただし、読み込みには6個中3個の読み込みでオペレーションが完了しますので、
**書き込みオペレーションが成功すると読み込む先のストレージは常に最新になる仕組み**です。

Auroraではストレージを共有している都合上レプリケーションに対して同期という単語は使っていませんが、見え方としては同期レプリケーションというのが適切でしょう。

加えて、Auroraはどのストレージノードが最新か、という情報を持っています。
そのため、書き込みは非同期ではありますが、読み込む情報は10-20msのディレイ後、常に最新になります。


10-20msのディレイが発生する理由としては、**マスターからレプリカへのページ（テーブル）キャッシュの更新リクエストがある**ためです。

参考：[table_cacheの意味と仕組み](https://shibainu55.hatenadiary.org/entry/20090922/1253617706)
参考：[Amazon Aurora ストレージと信頼性](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/Aurora.Overview.StorageReliability.html)



クォーラムモデルについては以下
> 参考：[クォーラムモデルを使用したAWSデータベースサービスの違い、共通点の比較 －Amazon Aurora、Amazon DocumentDB、Amazon Neptuneの比較表 －](https://tech.nri-net.com/entry/comparison_of_aws_quorum_model_databases)

ここで紛らわしいのが、**6つのストレージへの書き込みは非同期**という文言です。
これは、６つのストレージに並行して(非同期に)書き込み処理を実施することを示します。
レプリケーションの同期、非同期とは意味合いが異なる点に注意です。


## (2) マルチマスタークラスター
### **同期**
...公式ドキュメント見つからず、、、消えた？

複数の書き込みインスタンス（現状２個）、同一リージョンにもてる機能です。
リージョン間レプリケーション、キャッシュは対応していません。
> ストレージを3AZに分散して持ち複数のデータベースノード上で書き込みが可能で、DBインスタンス間で書き込み後の読み込み整合性を持ちます。
> 参考；[【新サービス】Amazon Aurora Multi-Masterが一般公開になりました](https://dev.classmethod.jp/articles/amazon-aurora-multi-master-ga/)

とのことで、ストレージの仕組みがAuroraのような形式のため
ストレージ共有で同期レプリケーションのような形式になります。


## (3) Aurora Serverless
### **同期**

ストレージを共有しているため、同じく同期レプリケーションの形になります。


## (4) グローバルデータベース(1秒未満のレイテンシ)
### **非同期**
複数リージョンにまたがってAuroraデータベースを構築できる機能です。
別リージョンにAurora DBクラスタを校正し、ストレージ（クラスターボリューム）間をレプリケーションする形になります。
リージョン障害の際のRTO,RPOがスナップショットのクロスリージョンレプリケーションに比べ、迅速に可能となります。
セカンダリリージョンは読み込み専用の為、データの整合性は担保されます。


ちなみに、セカンダリリージョンからの書き込み転送機能の整合性について、
> セカンダリクラスターの読み取り整合性の程度を制御できます。読み取り整合性レベルは、一部またはすべての変更がプライマリクラスターからレプリケートされるように、各読み取りオペレーションの前にセカンダリクラスターが実行する待機時間を決定します。読み取り整合性レベルを調整して、セッションから転送されたすべての書き込みオペレーションが、後続のクエリの前にセカンダリクラスターに表示されるようにすることができます。
また、この設定を使用して、セカンダリクラスターのクエリに、常にプライマリクラスターからの最新の更新が表示されるようにすることもできます。
参考：[Amazon Aurora Global Database の書き込み転送を使用する](https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/aurora-global-database-write-forwarding.html#aurora-global-database-write-forwarding-isolation)


# おまけ：問題となること
この同期、非同期が問題になるのは障害時のデータ損失になります。
Auroraはストレージを共有し、さらには複数AZに分散しているため、データ損失は限りなく0に近くなります。


注意としてはAurora以外のRDSの非同期レプリケーションです。

、、、と思いましたが、Aurora以外のRDSのリードレプリカに関しては自動フェールオーバーは対応していないので、意図しないデータ損失は防がれています。
なるほど、、うまく考慮されていますね。。。

# 最後に

ここまで調べて、やっと同期レプリケーションについてわかりました。
Aurora→同期レプリケーションと呼ばない方が良い。（ボリュームの共有）
Aurora以外のRDS
　・マルチAZ配置:同期レプリケーション
　・マルチAZ DBクラスター：準同期レプリケーション
　・リードレプリカ：非同期レプリケーション
指摘がありましたら、遠慮なくお願いします。