gpt4 book ai didi

python - 如何使用 python 在 redis 中实现原子获取或设置和获取 key ?

转载 作者:IT王子 更新时间:2023-10-29 06:01:17 25 4
gpt4 key购买 nike

我有一个 Redis 服务器,我想实现一个原子(或伪原子)方法来执行以下操作(注意:我有一个与 Redis 服务器有多个 session 的系统):

  1. 如果某个键 K 存在,则获取它的值
  2. 否则,请调用 SETNX function具有由某些函数生成的随机值 F(生成 salts )
  3. 向 redis 询问当前 session 刚刚生成的键 K 的值(或由另一个 session “同时”生成 - 在当前 session 生成它之前的一小段时间)

我不想预先生成(在检查值是否存在之前)具有函数 F 的值,并在键不存在时使用它的原因是:

  1. 我不想毫无理由地调用 F(这可能会导致 CPU 密集型行为(
  2. 我想避免下一个有问题的情况:T1 : session 1 生成了一个随机值 VAL1T2: session 1 询问 key K 是否存在并得到“False”T3 : session 2 生成了一个随机值 VAL2T4: session 2 询问 key K 是否存在并得到“False”T5: session 2 调用 SETNX值为 VAL2 并从现在开始使用 VAL2T6: session 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)

还有其他解决方案吗?

最佳答案

是的,您可以使用 WATCH为了这。这是 redis-py 的修改示例:

def atomic_get_set(some_key):
with r.pipeline() as pipe:
try:
# put a WATCH on the key that holds our sequence value
pipe.watch(some_key)
# after WATCHing, the pipeline is put into immediate execution
# mode until we tell it to start buffering commands again.
# this allows us to get the current value of our sequence
if pipe.exists(some_key):
return pipe.get(some_key)
# now we can put the pipeline back into buffered mode with MULTI
pipe.multi()
pipe.set(some_key, F())
pipe.get(some_key)
# and finally, execute the pipeline (the set and get commands)
return pipe.execute()[-1]
# if a WatchError wasn't raised during execution, everything
# we just did happened atomically.
except WatchError:
# another client must have changed some_key between
# the time we started WATCHing it and the pipeline's execution.
# Let's just get the value they changed it to.
return pipe.get(some_key)

关于python - 如何使用 python 在 redis 中实现原子获取或设置和获取 key ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24775879/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com