我可以使用 lpop/rpop 来使用 Redis 创建一个简单的队列系统吗?

Can I use lpop/rpop to create a simple queue system with Redis?

我尝试了几个 message/job 队列系统,但它们似乎都增加了不必要的复杂性,而且我总是以队列进程无缘无故死机和神秘的日志消息告终。

所以现在我想用Redis做一个我自己的队列系统。你会怎么做?

据我所知,Redis 很好,因为它有 lpop 和 rpush 方法,还有一个 pub/sub 系统可以用来通知工作人员有新消息要使用。这是正确的吗?

是的,你可以。事实上,有许多软件包可以做到这一点......包括 Celery and RQ for Python and resque for Ruby and ports of resque to Java (Jesque and Javascript (Coffee-resque).

还有RestMQ which is implemented in Python, but designed for use with any ReSTful系统。

还有很多其他的。

请注意,Redis LIST 是最简单的网络排队系统。然而,让事情在 Redis 提供的简单原语上变得健壮是非常重要的(对于 "robust" 的某些值可能是不可能的——至少在服务器端是这样)。许多将 Redis 用作队列的库添加了旨在最大限度地减少丢失消息的机会的功能和协议,同时确保 "at-most-once" 语义。其中许多使用 RPOPLPUSH Redis 原语和辅助 LIST 上的一些其他处理来处理已完成工作的确认和 "lost" 单元的重新调度。 (考虑这样一种情况,某些客户作为 "popped" 队列中的一个工作单元并在工作结果发布之前死亡;您如何检测和缓解这种情况?)

在某些情况下,人们精心制作了服务器端(Redis Lua EVAL) scripting to handle more reliable queuing. For example implementing something like RPOPLPUSH but replacing the "push" with a ZADD (thus adding the item and a timestamp to a "sorted set" representing work that's "in progress"). In such systems the work is completed with a ZREM and scanned for "lost" work using ZRANGEBYSCORE.

以下是 Salvatore Sanfilippo(a.k.a。antirez,Redis 的作者)关于实现健壮排队系统的一些想法:Adventures in message queues where he discusses the considerations and forces which led him to work on disque .

我相信您会发现一些批评者认为 Redis 是 "real" 消息总线和队列系统(例如 RabbitMQ)的糟糕替代品。 Salvatore 在他的“博客条目”中说了很多,我欢迎其他人在这里阐明偏爱此类系统的令人信服的理由。

我的建议是在早期原型设计阶段从 Redis 开始;但要将您对系统的使用抽象为一些统一的代码。 Celery 等实际上为您做到了这一点。您可以开始将 Celery 与 Redis 后端一起使用,并轻松地将后端替换为 RabbitMQ 或其他对您的大部分代码几乎没有影响的后端。

如需备选方案目录,请考虑仔细阅读:http://queues.io/