尽管密钥存在,Redis spop仍返回null - NodeJS

时间:2015-12-16 15:31:58

标签: node.js heroku redis

我遇到此问题,spop Redis命令返回null,尽管数据库中存在一个键/条目。

我从未在本地计算机上运行的Redis服务器上遇到此问题。令人讨厌的是没有任何错误或任何错误。

我使用Redis Desktop Manager检查Heroku Redis数据库中的内容。

这是获取数据库中值的NodeJS代码:

redis.spop('id', function (err, result) {}

我可能会做的一件事情如下:我同时从数据库中获得最多6个进程popping值。

知道什么可能导致这种奇怪的行为?

技术规格:

  • Redis local:3.0.4
  • Redis remote:Heroku 3.0.3
  • NodeJS模块:ioredis

1 个答案:

答案 0 :(得分:3)

我的猜测是这样的事情正在发生:

  • 读者#1检查集合中是否还有数据
  • Redis返回“是的,我还剩一个项目”
  • 读者#2检查集合中是否还有数据
  • Redis返回“是的,我还剩一个项目”
  • Reader#1弹出此项目(清空集合)
  • Reader#2尝试弹出该项目,并返回null,因为该集合现在为空。

检查设置大小和弹出值之间存在竞争条件,这意味着在这两个操作之间有一个小时间窗口,另一个读者也可以弹出一个值(这就是为什么当你没有发生这个问题的原因)只有一个读者。)

Redis有一些列表的命令(比如BRPOP)等待实际项目弹出,但 sets 没有类似的东西。但是,Redis文档包含some example code,了解如何实现类似的功能。

或者,您可以实现某种形式的锁定,但这可能会对性能产生影响。

最后,如果你的读者从一个空集中弹出,也许它甚至不是一个大问题,在这种情况下,他们只会忽略null并稍后再检查。