【发布时间】:2016-08-04 04:32:45
【问题描述】:
我有一个 redis 服务器,我想实现一个原子(或伪原子)方法,它将执行以下操作(注意:我有一个与 redis 服务器有多个会话的系统):
- 如果某个键 K 存在,则获取它的值
- 否则,使用某个函数F(生成salts)生成的随机值调用SETNX function
- 向 redis 询问当前会话刚刚生成的键 K 的值(或由另一个会话“同时”生成 - 在当前会话生成之前不久)
我不想使用 F 函数预先生成(在检查值是否存在之前)一个值,并在键不存在时使用它的原因是:
- 我不想毫无理由地调用 F(这可能会导致 CPU 密集型行为(
- 我想避免下一个有问题的情况: T1 : 会话 1 生成一个随机值 VAL1 T2:会话 1 询问密钥 K 是否存在并得到“假” T3:会话 2 生成一个随机值 VAL2 T4:会话 2 询问密钥 K 是否存在并得到“假” T5:会话 2 调用 SETNX 并使用值 VAL2 并从现在开始使用 VAL2 T6:会话 1 调用 SETNX 并使用值 VAL1 并从现在开始使用 VAL1,其中键 K 的实际值为 VAL2
我创建的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)
还有其他解决方案吗?
【问题讨论】:
标签: python python-2.7 redis redis-py