我有一個應該寫入redis實例的密鑰和一個值的列表(對於所有密鑰都是一樣的)。這應該只會發生,如果具有此項的條目已經存在。redis:設置是否存在 - 通過python
有一個MSETNX命令,這是做相反的:放在條目中,當鑰匙確實不存在存在。
當然,我可以通過EXIST之前檢查,並根據結果進行設置,但我如何確保這個原子。由於這個列表可能非常龐大,我該如何做這個基於管線的?
我使用redis-py作爲包裝,並且服務器上沒有可用的Lua腳本。
我有一個應該寫入redis實例的密鑰和一個值的列表(對於所有密鑰都是一樣的)。這應該只會發生,如果具有此項的條目已經存在。redis:設置是否存在 - 通過python
有一個MSETNX命令,這是做相反的:放在條目中,當鑰匙確實不存在存在。
當然,我可以通過EXIST之前檢查,並根據結果進行設置,但我如何確保這個原子。由於這個列表可能非常龐大,我該如何做這個基於管線的?
我使用redis-py作爲包裝,並且服務器上沒有可用的Lua腳本。
這不是非常方便的沒有Lua,但它仍然可以使用WATCH/MULTI/EXEC命令完成。我們的想法是分割你巨大的鍵列表中的n項塊(N = 20爲例),然後應用下面的函數來每塊:
def process_block(redis_client, block, value):
with redis_client.pipeline() as pipe:
while True:
try:
pipe.watch(block)
to_set = [ for x in block if pipe.exists(x) ]
if to_set:
pipe.multi()
for x in to_set:
pipe.set(x, value)
pipe.execute()
break
except redis.WatchError:
continue
finally:
pipe.reset()
原子性是由WATCH保證/ MULTI/EXEC命令,你將管道1 WATCH,1 MULTI,最多n SET和1 EXEC命令。不過,您將支付EXISTS往返費。爲n選擇正確的值是流水因子和併發交互風險之間的折中。它不應該設置得太高。
不是我所期望的,但只要我不想更新,我就試試看。謝謝! – kraiz 2012-08-06 17:07:29
使用[SETNX](http://redis.io/commands/setnx)創建鎖定。這將使您的所有操作成爲原子。 – freakish 2012-08-06 13:21:51