直列化可能な整合性で軽量トランザクションを実行する方法

軽量トランザクションを使用する次期と理由。

分散データベースでは、データの読み取りおよび書き込みを厳密にシーケンシャルに行う必要がある場合、独特な問題があります。ユーザーのアカウント作成や送金のためのトランザクションでは、2つの潜在的な書き込み間の競合状態を調整して、1つの書き込みがもう一方の書き込みより優先されるようにする必要があります。DataStax Enterprise(DSE)データベースでは、Paxos合意プロトコルを使用して、同時操作を処理できる軽量トランザクションを実装しています。

Paxosプロトコルは、直列化可能な整合性を持つデータベースに実装され、リレーショナル・データベース管理システム(RDBMS)によって提供されるシリアライズ可能なレベルと同様のレベルでトランザクションの分離性を保証します。このタイプのトランザクションは、CAS(compare-and-set)として知られています。レプリカ・データが比較され、古いデータが最も整合性のある値に設定されます。DSEでは、このプロセスによって、Paxosプロトコルと通常の読み取り操作/書き込み操作が組み合わされ、CAS操作が実行されます。

Paxosプロトコルは一連のフェーズとして実装されます。
  1. 準備/約束
  2. 読み取り/結果
  3. 提案/受諾
  4. コミット/確認

これらのフェーズは、プロポーザーとアクセプター間で発生するアクションです。どのノードもプロポーザーになることができ、複数のプロポーザーが同時に動作できます。わかりやすくするため、この説明では1つのプロポーザーのみを使用します。

プロポーザーは、プロポーザル番号を含むアクセプターのクォーラムにメッセージを送信して、準備されます。各アクセプターは、プロポーザル番号が受け入れた最も大きな番号の場合に、そのプロポーザルを受け入れることを約束します。プロポーザーがアクセプターのクォーラムから約束を受け取ると、プロポーザルの値が各アクセプターから読み取られ、再度プロポーザーに送られます。プロポーザーが使用する値を決定し、その値をプロポーザル番号とともにアクセプターのクォーラムに提案します。各アクセプターは、大きな番号を持つプロポーザルにまだ約束していない場合、特定の番号のプロポーザルを受諾します。この値は、すべての条件が満たされた場合、書き込み操作としてコミットおよび認識されます。

これらの4つのフェーズでは、軽量トランザクションを提案するノードと、このトランザクションに含まれるクラスターのレプリカ間に4回の往復を要求します。このため、パフォーマンスは影響を受けます。同時実行を考慮する必要がある状況では、軽量トランザクションを予約します。

軽量トランザクションは、他の軽量トランザクションが発生するのをブロックしますが、通常の読み取り操作および書き込み操作の発生は停止しません。軽量トランザクションでは、通常の操作とは異なるタイムスタンプ・メカニズムを使用するため、軽量トランザクションと通常の操作を混在させると、エラーが発生します。軽量トランザクションがパーティション内の行への書き込みに使用された場合、読み取り操作および書き込み操作の両方の軽量トランザクションのみが使用されます。これは、個々の処理かバッチ処理かにかかわらず、すべての操作に該当する注意事項です。

たとえば、以下の一連の操作は失敗する可能性があります。
DELETE ...
INSERT .... IF NOT EXISTS
SELECT ....
以下の一連の操作は機能します。
DELETE ... IF EXISTS
INSERT .... IF NOT EXISTS
SELECT .....

直列化可能な整合性による読み取り

SERIAL整合性レベルを使用すると、新しい追加や更新を行おうとせずに、現在の(さらにコミットされていない可能性がある)データの状態を読み取ることができます。SERIALの読み取りにおいて進行中のコミットされていないトランザクションが見つかった場合、データベースはコミットの一環としてread repairを実行します。