redis.pipeline()的局限性
假设我使用 Redis
来创建和维护一个哈希表 h[ url ] = t
,其中 t
是页面 url
最近访问的时间戳。现在,给定一个输入 ( url, newT )
,我想做以下几件事:
- 检查
url
是否是h
的一个键 - 如果不是,就设置
h[ url ] = newT
- 如果是,就比较旧的时间戳
h[ url ]
和newT
,如果newT
更大,就更新它
另外,我想使用 multiprocessing
,所以我需要确保这个过程是原子性的。在看了文档后,我认为可以使用 pipeline
来实现:
此外,管道可以确保缓冲的命令作为一个整体原子性地执行。这是默认的行为。
但接下来它说:
当需要原子事务但又需要在事务中使用 Redis 中的值时,常常会出现问题。例如,假设 INCR 命令不存在,我们需要在 Python 中构建一个原子版本的 INCR。
一个完全简单的实现可能是先获取值,然后在 Python 中增加它,最后再把新值设置回去。然而,这并不是原子性的,因为多个客户端可能同时在做这个,每个客户端都从 GET 中获取到相同的值。
这时就需要用到 WATCH 命令。[...]
我的理解是,如果我想在更新之前读取 h[ url ]
的值,就不能使用 pipeline
。我的理解正确吗?为什么这样不行呢?
1 个回答
1
管道(Pipeline)可以让你一次性发送一批命令。
如果你需要获取一些值,然后在Python中进行计算,再执行更多的Redis命令,这样就无法在一个批次里完成了。
你有两个选择:
- 使用WATCH命令来检查,自上次尝试以来,相关的键是否没有改变。
- 使用Lua脚本,在服务器端进行计算。