データベースのレプリケーションと整合性をざっくり理解する
はじめに
個人での開発や、小規模なアプリケーションでは整合性を意識して開発することは少ないかもしれませんが、複雑なシステムや大規模なアプリケーションでは整合性を意識して開発することが重要になってきます。
今回はデータベースの整合性の中でも一般的な、「結果整合性」と「強い整合性」について調べたことをざっくりまとめました!
これまで整合性についてあまり意識してなかったという方の参考になれば幸いです!
レプリケーション
整合性を理解するにあたって、レプリケーションの仕組みが重要になってきます。
レプリケーションとは、データベースが持つデータを他のサーバに複製し、データの可用性と信頼性を高める手法です。
例えば、トラフィックが多いサービスでは、データベースに負荷がかかりやすいため、レプリケーションを行うことで読み取り負荷を分散させることが重要です。また、データベースの障害に備えて、データのバックアップとしても利用されます。
個人でDockerなどを使ってデータベースを立ち上げている場合はレプリケーションを意識することはほとんどないかもしれませんが、AWSやGCPなどのクラウドサービスを使っている場合は、内部的にレプリケーションが行われていることが多いです。
レプリケーションの仕組みと整合性
レプリケーションを行うシステムで重要になるのが、レプリケーションが同期的に行われるのか、非同期的に行われるのかです。
同期レプリケーション
同期レプリケーションでは、マスターノードに書き込まれたデータが、全てのレプリカに確実に反映されたことが確認されるまでクライアントにレスポンスが返されません。これによりデータの整合性が保たれ、「強い整合性」が確保されます。
- メリット: データの整合性が保たれ、常に最新のデータにアクセスできる
- デメリット:全てのレプリカへの書き込み完了を待つため、書き込み処理に遅延が発生する可能性がある
非同期レプリケーション
非同期レプリケーションでは、マスターノードがレプリカへの書き込みを完了する前にクライアントへレスポンスを返します。これにより、高速な応答が可能になりますが、一時的にデータの不整合が発生する可能性があります。
このように、即座の整合性は保証しないが、最終的には全てのレプリカが最新のデータに追いつくことを保存する整合性レベルを、「結果整合性」と呼びます。
- メリット:書き込み処理が高速
- デメリット:一時的にデータの不整合が発生し、古いデータを参照する可能性がある
整合性のユースケース
クラウドサービスや大規模なアプリケーションでは、整合性のレベルを適切に選択することが重要になってきます。
強い整合性
金融取引やショッピングサイトの決済など、データの整合性が重要なシステムでは、すべてのクライアントが常に最新のデータにアクセスできる必要があります。
この場合は、強い整合性を確保するために、同期レプリケーションを採用することが一般的です。
しかし、同期レプリケーションは書き込み処理に遅延が発生するため、高速な応答が求められるシステムでは適していません。
AWSでは、RDSやAuroraなどのサービスで強い整合性を採用しています。
結果整合性
SNSのタイムラインやニュースサイトの記事の投稿では、多少の遅延が許容されるため、結果整合性が選択肢として考えられます。
この場合は、非同期レプリケーションを採用することで、高速な応答を実現することが可能です。
特に、トラフィックが多いサービスでは、高速な応答が求められるため、結果整合性を採用することが多いです。
AWSでは、DynamoDBが結果整合性を採用しており、高速な応答が求められるサービスに適しています。(ただし、強い整合性を選択することも可能です)
各レプリケーションの問題点
以上は、ざっくりとした整合性の説明でしたが、レプリケーションに発生しうる問題点とその解決法をもう少し深掘りしてみます。
同期レプリケーションの問題
同期レプリケーションでは、全てのレプリカへの書き込み完了を待つため、書き込み処理に遅延が発生する可能性があることを述べました。
実際には、データベースで同期型のレプリケーションを有効にする場合、通常は1つを同期型にして、残りを非同期型にします。
これにより、データの整合性を保ちつつ、書き込み処理の遅延を抑えることができます。
この構成を準同期型(semi-synchronous) と呼びます。
非同期レプリケーションの問題
非同期レプリケーションでは、色々な問題が発生する可能性があります。
データの不整合
非同期レプリケーションでは、一時的にデータの不整合が発生する可能性を述べました。これをダイアグラム的に表してみます。
まず、ユーザーAが商品を購入し、マスターノードの在庫が0になります。レプリケーションが完了していない段階で、ユーザーBがレプリカノードの在庫を確認すると、古い在庫データ(残り1個)が返されてしまいます。
モノトニックな読み取り
非同期レプリケーションが生じる問題の2つ目の例は、過去に遡ってデータを読み取ってしまう可能性です。
以下の図では、ユーザーBが同じクエリを2回実行していますが、1回目はラグの小さなレプリカノードにアクセスし、2回目はラグの大きなレプリカノードにアクセスしています。
(こういった状況は、リクエストがランダムなサーバーに送信される場合に発生します)
この場合、ユーザーは同じクエリを実行しているのにもかかわらず、取得するデータの時間が巻き戻ってしまっています。
このような問題を解決するために、モノトニックな読み取りという概念があります。
モノトニックな読み取りでは、古いデータを参照することはあるものの、連続して行った複数の読み取り操作で、時間が巻き戻らないことを保証します。
このような読み取りを実現する方法の1つは、各ユーザーが同じレプリカノードにアクセスするようにすることです。
まとめ
データベースのレプリケーションと整合性についてざっくりと説明しました。
整合性レベル | 使用ケース | メリット | デメリット |
---|---|---|---|
強い整合性 | 金融取引、決済 | データ整合性を即座に保証 | 書き込み遅延が発生 |
結果整合性 | SNSのタイムライン | 応答が高速で、スケーラブル | 一時的な不整合の可能性 |
技術選定において、整合性のレベルという観点から議論できるようにしたいです。
この記事が参考になれば幸いです!
参考文献
Discussion