AWSの優れたDBエンジンの一つである、あの「Amazon Aurora」について、読み取り時のデータ整合性のことが少し気になったらしく、ちょっと調べてみたりしたんですって。
内容には誤りがあるかもしれません。お気付きの場合にはコメント等でご指摘いただけますと幸いです。
読み込み整合性
いきなりAuroraではないのですが、読み込み整合性に関して「Amazon DynamoDB」というDBのお話を少し。
DynamoDBはAWSにて提供されている、NoSQLのDBサービスです。DynamoDBでは、データの読み込みオペレーションとして、2種類が用意されています。
結果整合性のある読み込み(Eventually Consistent Reads)
DynamoDB テーブルからの読み込みオペレーションの応答には、最近の書き込みオペレーションの結果が反映されていないことがあります。応答には古いデータが含まれる場合があります。少し時間がたってから読み込みリクエストを繰り返すと、応答で最新のデータが返されます。
読み込みリクエストの直前に書き込みが行われていた場合などに、直前の書き込みが反映されていないデータをレスポンスとして返す可能性があります。
複数ストレージでレプリケーションが行われるような状況では、実際に全てのストレージへの書き込み完了を待つことなく、特定の基準を満たせば書き込みオペレーションが完了したと見なして処理を進めることがあります。
DynamoDBでも同様の仕様ということでしょうか。レスポンス速そう。
強力な整合性のある読み込み(Strongly Consistent Reads)
強力な整合性のある読み込みをリクエストすると、DynamoDB は成功した以前のすべての書き込みオペレーションからの更新が反映された最新データの応答を返します 。ただし、この整合性には以下のような欠点があります。
・強力な整合性のある読み込みは、ネットワークの遅延または停止があった場合には利用できなくなる可能性があります。この場合、DynamoDB はサーバーエラー (HTTP 500) を返す場合があります。
・強力な整合性のある読み込みでは、結果整合性のある読み込みよりもレイテンシーが高くなる場合があります。
・グローバルセカンダリインデックス (GSI) では、強力な整合性のある読み込みはサポートされていません。
・強力な整合性のある読み込みでは、結果整合性のある読み込みよりも多くのスループット容量が使用されます。詳細については、読み込み/書き込みキャパシティーモード を参照してください。
「結果整合性のある読み込み」とは異なり、直前に行われた書き込みの内容が反映された、時間軸で見て整合性のあるレスポンスを返す方式です。堅い感じ。
「結果整合性のある読み込み」と「強力な整合性のある読み込み」はユースケースに応じて使い分けるのが良さそう、という定型文を置いておきます。
AuroraDBクラスターのエンドポイント
やっとAuroraのエンドポイントの話になります。
そも、Auroraは下記のようなエンドポイントを持ちます。[4]
クラスターエンドポイント
AuroraDBクラスターの「書き込みエンドポイント」を指します。
例)mydbcluster.cluster-123456789012.us-east-1.rds.amazonaws.com:3306
リーダーエンドポイント
AuroraDBクラスターの「読み取りエンドポイント」を指します。
クラスターに1つ以上のAuroraレプリカが含まれる場合、ラウンドロビンDNSによって自動で負荷分散が行われます。
例)mydbcluster.cluster-ro-123456789012.us-east-1.rds.amazonaws.com:3306
カスタムエンドポイント
ユーザーが作成可能なエンドポイントです。AuroraDBクラスター内のいくつかのDBインスタンスのみを選択して、負荷分散を行うといったことができるようです。
例)myendpoint.cluster-custom-123456789012.us-east-1.rds.amazonaws.com:3306
インスタンスエンドポイント
AuroraDBクラスター内のそれぞれのインスタンスが個別に持つエンドポイントです。通常の負荷分散以上にきめ細かいロードバランシングを行いたいような場合や、特に個別のインスタンスに接続したいような場合の利用が想定されます。
例)mydbinstance.123456789012.us-east-1.rds.amazonaws.com:3306
Q. Auroraの読み込み整合性ってどうなっているの?
- クラスターエンドポイントを利用する場合、書き込みと読み込みを1つのエンドポイントで行う事になります。
- この場合、レプリカラグを考慮する必要がなく、Auroraの書き込み/読み取り成功の判定条件(Quorum原理)によれば、強い整合性が保たれると考えられます。
- 読み書きの成否判定について、書き込み成功の基準は「過半数」、読み取り成功の基準は「半数以上」が設定されているため、理論上は古いデータが返ることはなさそうに見えます。
- また、Auroraは分散したストレージを単一の論理ボリュームとして認識する構成であるため、やはり構築上古いデータが返ることはない(ようにできている)と考えて良さそうです。[6] [7]
- リーダーエンドポイント含むその他のエンドポイントを利用する場合には、レプリカラグが影響してきます。
- 書き込みから読み取りの間隔を超えるラグが生じていた場合、書き込み完了前のデータを読み取ってしまう可能性があると考えられます。
- DBの変更頻度にもよりますが、レプリカラグは通常100ミリ秒未満です。[6]
- マルチマスタークラスター構成の場合には、設定で強い整合性を要求することができるようですが、パフォーマンスとトレードオフになるようです。[5]
- 詳細は割愛。
読み込み整合性について明記した資料が見当たらないなと思ったのですが、読み書きのアーキテクチャ面で理論的に強い整合性が保たれているため、整合性という文脈での説明が不要なのかもしれません。すごい。
Q. AuroraDBクラスターにプライマリしか置いてない場合、エンドポイントはどうなるの?
- Auroraクラスターにプライマリインスタンスしか含まれていない場合でも、リーダーエンドポイントは作成されます。
- AuroraDBクラスターに含まれるインスタンスがプライマリインスタンス1台のみである(=レプリカが含まれていない)場合、リーダーエンドポイントに接続した場合でも、プライマリインスタンスに接続されます。
- この場合、リーダーエンドポイントを介して書き込みオペレーションが実行できます。[4]
- AuroraDBクラスターに含まれるインスタンスがプライマリインスタンス1台のみである(=レプリカが含まれていない)場合、リーダーエンドポイントに接続した場合でも、プライマリインスタンスに接続されます。
書き込み権限は接続したエンドポイントではなく、接続先のDBインスタンスによって判断されるという仕様のようです。
まあでも権限の割り当てはインスタンスごとだし、プライマリに接続される以上はそりゃそうか?なるほど。
参考
- [1] Amazon Aurora の PoC (概念実証) の実行 – Amazon Aurora
- [2] Amazon Aurora DB クラスターへの接続 – Amazon Aurora
- [3] Amazon RDS Proxy による接続の管理 – Amazon Aurora
- [4] Amazon Aurora 接続管理 – Amazon Aurora
- [5] Aurora マルチマスタークラスターを使用する – Amazon Aurora
- [6] Amazon Aurora でのレプリケーション – Amazon Aurora
- [7] Amazon Aurora ストレージと信頼性 – Amazon Aurora
- [8] 読み込み整合性 – Amazon DynamoDB