私は redis サーバーを持っており、次のことを行うアトミック (または疑似アトミック) メソッドを実装したいと考えています (注意: Redis サーバーへの複数のセッションを持つシステムがあります):
- いくつかのキーKが存在する場合、その値を取得します
- それ以外の場合は、関数F ( salt を生成する)によって生成されたランダムな値を使用してSETNX 関数を呼び出します。
- 現在のセッションによって生成されたばかりのキーKの値を redis に問い合わせます(または、別のセッションによって "同時に" - 現在のセッションが生成する少し前)。
(値が存在するかどうかを確認する前に) 関数Fで値を事前に生成し、キーが存在しない場合はそれを使用したくない理由は次のとおりです。
- 正当な理由もなくFを呼び出したくありません(集中的な CPU 動作を引き起こす可能性があります (
- 次の問題を回避したい : T1 : セッション 1 がランダムな値VAL1を生成した T2 : セッション 1 がキーKが存在するかどうかを尋ね、「False」を取得した T3 : セッション 2 がランダムな値VAL2を生成した T4 : セッション 2 がキーKが存在する かどうかを尋ねたT5 : セッション 2 は、値VAL2でSETNXを呼び出し、これからVAL2を使用しますT6 : セッション 1 は、値VAL1でSETNXを呼び出し、これからキーKの実際の値がVAL2であるVAL1を使用します
私が作成したpython疑似コードは次のとおりです。
import redis
r = redis.StrictRedis(host='localhost', port=6379, db=0)
''' gets the value of key K if exists (r.get(K) if r.exists(K)),
otherwise gets the value of key K if calling SETNX function returned TRUE
(else r.get(K) if r.setnx(K,F())), meaning this the sent value is really the value,
otherwise, get the value of key K, that was generated by another session a
short moment ago (else r.get(K))
The last one is redundant and I can write "**r.setnx(K,F()) or True**" to get the
latest value instead, but the syntax requires an "else" clause at the end '''
r.get(K) if r.exists(K) else r.get(K) if r.setnx(K,F()) else r.get(K)
別の解決策はありますか?