我有一个问题,尽管数据库中存在一个键/条目,但 spop
Redis 命令返回 null
。
我在本地机器上运行的 Redis 服务器上从未遇到过这个问题。烦人的是没有错误什么的。
我使用 Redis 桌面管理器检查 Heroku Redis 数据库中的内容。
这是获取数据库中值的 NodeJS 代码:
redis.spop('id', function (err, result) {}
我可能会做的一件与众不同的事情如下:我最多有 6 个进程同时从数据库中弹出
值。
知道什么会导致这种奇怪的行为吗?
技术规范:
- 本地Redis:3.0.4
- Redis 远程:Heroku 3.0.3
- NodeJS 模块:ioredis
最佳答案
我的猜测是这样的事情正在发生:
- Reader #1 检查集合中是否还有数据
- Redis 返回“是的,我还剩一件”
- Reader #2 检查集合中是否还有数据
- Redis 返回“是的,我还剩一件”
- 读者 #1 弹出这个项目(清空集合)
- Reader #2 尝试弹出该项目,并返回一个
null
,因为该集合现在是空的。
在检查集合大小和弹出一个值之间存在竞争条件,这意味着在这两个操作之间有一个小的时间窗口,另一个读取器也可以弹出一个值(这就是为什么当你只有一个读者)。
Redis 有一些用于列表 的命令(如 BRPOP
),它们会等到有实际项目要弹出,但没有任何类似的集合。但是,Redis 文档包含 some example code关于如何实现类似的东西。
或者,您可以实现某种形式的锁定,尽管这可能会对性能产生影响。
最后,如果您的读者从空集中弹出,也许这甚至不是什么大问题,在这种情况下,他们会忽略 null
并稍后再次检查。
关于node.js - 尽管存在 key ,Redis spop 仍返回 null - NodeJS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34315973/