4

コードのブロックを楽観的に「ロック」したい。擬似コードは次のとおりです。

revision = GET('lock_key') # default as 0
{
<<block of code>>
}
new_revision = INCR('lock_key')
if new_revision != revision + 1:
    raise Exception # now retry or whatever

INCR と GET の両方がアトミックであるため、これは問題ないように見えます。このアプローチに問題はありますか?

4

1 に答える 1

5

このアプローチにはいくつかの問題があります。第一に、2 ワーカーを超えるとスケーリングがうまくいきません。なぜなら、速いワーカーは遅いワーカーを枯渇させるからです。フローには原子性も欠けています。これは、実行しているロジックによっては問題になる場合とそうでない場合がありますが、競合状態は厄介です。最後に、常に key_lock を INCRing しているため、オブザーバー効果が少しあります。

より良いアプローチは、Redis のMULTIEXEC、およびWATCHを使用することです。Redis のトランザクション トピックでは、これについてかなりきちんと説明されており、疑似コードに基づいて次の例が提供されています。

WATCH('lock_key')
revision = GET('lock_key') # default as 0
{
    <<block of code>>
}

MULTI()
new_revision = INCR('lock_key')
if EXEC() is None:
  raise Exception # now retry or whatever
于 2014-05-14T16:00:58.517 に答える