redis.pipeline()的局限性

1 投票
1 回答
1578 浏览
提问于 2025-04-18 13:13

假设我使用 Redis 来创建和维护一个哈希表 h[ url ] = t,其中 t 是页面 url 最近访问的时间戳。现在,给定一个输入 ( url, newT ),我想做以下几件事:

  1. 检查 url 是否是 h 的一个键
  2. 如果不是,就设置 h[ url ] = newT
  3. 如果是,就比较旧的时间戳 h[ url ]newT,如果 newT 更大,就更新它

另外,我想使用 multiprocessing,所以我需要确保这个过程是原子性的。在看了文档后,我认为可以使用 pipeline 来实现:

此外,管道可以确保缓冲的命令作为一个整体原子性地执行。这是默认的行为。

但接下来它说:

当需要原子事务但又需要在事务中使用 Redis 中的值时,常常会出现问题。例如,假设 INCR 命令不存在,我们需要在 Python 中构建一个原子版本的 INCR。

一个完全简单的实现可能是先获取值,然后在 Python 中增加它,最后再把新值设置回去。然而,这并不是原子性的,因为多个客户端可能同时在做这个,每个客户端都从 GET 中获取到相同的值。

这时就需要用到 WATCH 命令。[...]

我的理解是,如果我想在更新之前读取 h[ url ] 的值,就不能使用 pipeline。我的理解正确吗?为什么这样不行呢?

1 个回答

1

管道(Pipeline)可以让你一次性发送一批命令。

如果你需要获取一些值,然后在Python中进行计算,再执行更多的Redis命令,这样就无法在一个批次里完成了。

你有两个选择:

  • 使用WATCH命令来检查,自上次尝试以来,相关的键是否没有改变。
  • 使用Lua脚本,在服务器端进行计算。

撰写回答