8

Redis を使用して、コマンドのアトミック シーケンスを実行したいと考えています。つまり、シーケンスの実行中に、他のクライアントがデータベースで変更を実行しないことを保証する必要があります。

書き込みコマンドのみを使用した場合はMULTI、 andEXECステートメントを使用して、トランザクションを使用して原子性を保証できます。ただし、トランザクションで読み取りコマンドも使用したいと考えています。したがってMULTI、読み取りコマンドもキューに入れられているため、使用できません!

基本的に、アトミックな方法で、次のことを行う必要があります。

  1. データベースから読み取りx
  2. に基づいて、データベースxに保存f(x)します。

1. と 2. の両方が、単一のアトミック トランザクションの一部である必要があります。

それを行う簡単な方法はありますか?

4

1 に答える 1

15

あなたの問題には2つの良い解決策があります。

オプション1:

WATCH読み取り元のキーでa を発行する必要があります。トランザクションは次のようになります。

WATCH x
x = GET x
MULTI
SET y, f(x)
EXEC

この例では、マルチ ブロック内の書き込みコマンドがアトミックに実行されますが、呼び出されてからkey の値が変更されていない場合のみです。これは楽観的ロックと呼ばれます。の値が変更された場合、アプリケーションでエラーが発生し、次に何をすべきかを決定する必要があります。その場合、 の新しい値を使用して再試行される可能性があります。xWATCHxx

オプション 2:

Redis は lua スクリプトをサポートするようになり、lua スクリプトはアトミックに実行されます。ロジックを lua スクリプトにカプセル化できれば、キーの読み取り、f(x)ロジックの実行、結果の保存をすべてアトミックに行うことができます。これは、実行しているロジックによっては、トリッキーであったり、オプションではない場合もあります。redis に実行させたいスクリプトに値を直接ハードコーディングして lua に値を渡すなどの醜いハックをしなければならないことさえあるかもしれません。とはいえ、このメソッドが機能するようになれば、信頼性とパフォーマンスが高く、処理のEXEC失敗に対処する必要はありません。

于 2013-08-27T07:06:00.380 に答える