日本語

分散トランザクションと二相コミット(2PC)プロトコルを深く掘り下げます。アーキテクチャ、利点、欠点、グローバルシステムでの応用について学びます。

分散トランザクション:二相コミット(2PC)の詳細

ますます相互接続が進む現代において、アプリケーションはしばしば、複数の独立したシステムにまたがるデータと対話する必要があります。これにより、分散トランザクションの概念が生じます。これは、単一の論理操作が複数のデータベースまたはサービスにわたる変更を必要とする状況です。このようなシナリオでデータ整合性を確保することは最重要であり、それを達成するための最もよく知られたプロトコルの1つが二相コミット(2PC)です。

分散トランザクションとは?

分散トランザクションとは、地理的に分散された複数のシステム上で実行される一連の操作であり、単一の原子単位として扱われます。これは、トランザクション内のすべての操作が成功(コミット)するか、どれも成功しない(ロールバック)ことを意味します。この「すべてか無か」の原則により、分散システム全体でのデータ完全性が保証されます。

東京の顧客が、ある航空会社のシステムで東京からロンドンへのフライトを予約し、同時に別のホテルの予約システムでロンドンのホテルの部屋を予約するというシナリオを考えてみてください。これらの2つの操作(フライト予約とホテル予約)は、理想的には単一のトランザクションとして扱われるべきです。フライト予約が成功してもホテル予約が失敗した場合、顧客が宿泊なしでロンドンに取り残されるのを避けるために、システムは理想的にはフライト予約をキャンセルすべきです。この協調的な動作が、分散トランザクションの本質です。

二相コミット(2PC)プロトコルの導入

二相コミット(2PC)プロトコルは、複数のリソースマネージャー(例:データベース)にわたって原子性を保証する分散アルゴリズムです。これには、中央のコーディネーターと、それぞれが特定のリソースの管理を担当する複数の参加者が関与します。プロトコルは2つの明確なフェーズで動作します。

フェーズ1:準備フェーズ

このフェーズでは、コーディネーターはトランザクションを開始し、各参加者にトランザクションのコミットまたはロールバックの準備をするように依頼します。関連する手順は次のとおりです。

  1. コーディネーターが準備要求を送信:コーディネーターは、すべての参加者に「準備」メッセージを送信します。このメッセージは、コーディネーターがトランザクションをコミットする準備ができたことを示し、各参加者にその準備をするように要求します。
  2. 参加者が準備して応答:各参加者は準備要求を受け取り、以下の操作を実行します。
    • トランザクションをコミットまたはロールバックする準備をするために必要な手順(例:リドゥ/アンドウログの書き込み)を実行します。
    • コーディネーターに「投票」を送信します。「コミット準備完了」(「はい」票)または「コミット不可」(「いいえ」票)のいずれかを示します。「いいえ」票は、リソースの制約、データ検証の失敗、またはその他のエラーが原因である可能性があります。

参加者は、一度「はい」と投票したら、変更をコミットまたはロールバックできることを保証することが重要です。これには通常、変更を安定ストレージ(例:ディスク)に永続化することが含まれます。

フェーズ2:コミットまたはロールバックフェーズ

このフェーズは、準備フェーズで参加者から受け取った投票に基づいてコーディネーターによって開始されます。2つの可能な結果があります。

結果1:コミット

コーディネーターがすべての参加者から「はい」票を受け取った場合、トランザクションのコミットに進みます。

  1. コーディネーターがコミット要求を送信:コーディネーターは、すべての参加者に「コミット」メッセージを送信します。
  2. 参加者がコミット:各参加者はコミット要求を受け取り、トランザクションに関連する変更をリソースに永続的に適用します。
  3. 参加者が確認:各参加者は、コミット操作が成功したことを確認するために、コーディネーターに確認メッセージを返信します。
  4. コーディネーターが完了:すべての参加者から確認を受け取ると、コーディネーターはトランザクションを完了としてマークします。

結果2:ロールバック

コーディネーターが、いずれかの参加者から1つの「いいえ」票を受け取った場合、または参加者からの応答を待っている間にタイムアウトした場合、トランザクションをロールバックすると決定します。

  1. コーディネーターがロールバック要求を送信:コーディネーターは、すべての参加者に「ロールバック」メッセージを送信します。
  2. 参加者がロールバック:各参加者はロールバック要求を受け取り、トランザクションの準備のために行われた変更をすべて元に戻します。
  3. 参加者が確認:各参加者は、ロールバック操作が成功したことを確認するために、コーディネーターに確認メッセージを返信します。
  4. コーディネーターが完了:すべての参加者から確認を受け取ると、コーディネーターはトランザクションを完了としてマークします。

例:Eコマース注文処理

注文に在庫データベースの更新と別個の決済ゲートウェイでの支払い処理が含まれるEコマースシステムを考えてみましょう。これらは、分散トランザクションに参加する必要のある2つの別個のシステムです。

  1. 準備フェーズ:
    • Eコマースシステム(コーディネーター)は、在庫データベースと決済ゲートウェイに準備要求を送信します。
    • 在庫データベースは、要求されたアイテムが在庫にあるか確認し、それらを予約します。成功した場合は「はい」票を、在庫切れの場合は「いいえ」票を返します。
    • 決済ゲートウェイは支払いを事前承認します。成功した場合は「はい」票を、承認が失敗した場合(例:残高不足)は「いいえ」票を返します。
  2. コミット/ロールバックフェーズ:
    • コミットシナリオ:在庫データベースと決済ゲートウェイの両方が「はい」票を返した場合、コーディネーターは両方にコミット要求を送信します。在庫データベースは在庫数を永続的に減らし、決済ゲートウェイは支払いをキャプチャします。
    • ロールバックシナリオ:在庫データベースまたは決済ゲートウェイのいずれかが「いいえ」票を返した場合、コーディネーターは両方にロールバック要求を送信します。在庫データベースは予約されたアイテムを解放し、決済ゲートウェイは事前承認を無効にします。

二相コミットの利点

二相コミットの欠点

二相コミットの代替手段

2PCの制限のため、分散トランザクションを管理するためのいくつかの代替アプローチが登場しました。これらには以下が含まれます。

二相コミットの実用的な応用

その制限にもかかわらず、2PCは強い整合性が重要な要件であるさまざまなシナリオで依然として使用されています。例としては以下が挙げられます。

二相コミットの実装

2PCの実装には、さまざまな要因を慎重に考慮する必要があります。これらには以下が含まれます。

分散トランザクションのグローバルな考慮事項

グローバル環境で分散トランザクションを設計および実装する場合、いくつかの追加の要因を考慮する必要があります。

結論

分散トランザクションと二相コミット(2PC)プロトコルは、堅牢で一貫性のある分散システムを構築するための不可欠な概念です。2PCは原子性を保証するためのシンプルで広く採用されているソリューションを提供しますが、特にブロッキングと単一障害点に関するその制限は、Sagasや最終的な整合性のような代替アプローチの慎重な検討を必要とします。強い整合性、可用性、パフォーマンスの間のトレードオフを理解することは、特定のアプリケーションのニーズに最適なアプローチを選択するために不可欠です。さらに、グローバル環境で運用する場合、ネットワーク遅延、タイムゾーン、データローカリゼーション、および規制遵守に関する追加の考慮事項に対処して、分散トランザクションの成功を確保する必要があります。

分散トランザクション:二相コミット(2PC)の詳細 | MLOG