微信号:infoqchina

介绍:有内容的技术社区媒体

Disque:Redis之父新开源的分布式内存作业队列

2015-05-10 18:14 InfoQ


DisqueRedis之父Salvatore Sanfilippo新开源的一个分布式内存消息代理。它适应于“Redis作为作业队列”的场景,但采用了一种专用、独立、可扩展且具有容错功能的设计,兼具Redis的简洁和高性能,并且用C语言实现为一个非阻塞网络服务器。有一点需要提请读者注意,在Disque项目文档及本文中,“消息(Message)”和“作业(Job)”可互换。


Disque是一个独立于Redis的新项目,但它重用了Redis网络源代码、节点消息总线、库和客户端协议的一大部分。由于Disque使用了与Redis相同的协议,所以可以直接使用Redis客户端连接Disque集群,只是需要注意,Disque的默认端口是7711,而不是6379。


作为消息代理,Disque充当了需要进行消息交换的进程之间的一个中间层,生产者向其中添加供消费者使用的消息。这种生产者-消费者队列模型非常常见,其主要不同体现在一些细节方面:

Disque是一个同步复制作业队列,在默认情况下,新增任务会复制到W个节点上,W-1个节点发生故障也不会影响消息的传递。


Disque支持至少一次和至多一次传递语义,前者是设计和实现重点,而后者可以通过将重试时间设为0来实现。每个消息的传递语义都是单独设置的,因此,在同一个消息队列中,语义不同的消息可以共存。


按照设计,Disque的至少一次传递是近似一次传递,它会尽力避免消息的多次传递。


Disque集群的所有节点都有同样的角色,也就是“多主节点(multi-master)”。生产者和消费者可以连接到不同的队列或节点,节点会根据负载和客户端请求自动交换消息。


Disque支持可选的异步命令。在这种模式下,生产者在向一个复制因子不为1的队列中添加一个作业后,可以不必等待复制完成就可以转而执行其它操作,节点会在后台完成复制。


在超过指定的消息重试时间后,Disque会自动将未收到响应的消息重新放入队列。


在Disque中,消费者使用显式应答来标识消息已经传递完成。


Disque只提供尽力而为排序。队列根据消息创建时间对消息进行排序,而创建时间是通过本地节点的时钟获取的。因此,在同一个节点上创建的消息通常是按创建顺序传递的,但Disque并不提供严格的FIFO语义保证。比如,在消息重新排队或者因为负载均衡而移至其它节点时,消息的传递顺序就无法保证了。所以,Salvatore指出,从技术上讲,Disque严格来说并不是一个队列,而更应该称为消息代理。


Disque通过四个参数提供了细粒度的作业控制,分别是复制因子(指定消息的副本数)、延迟时间(将消息放入队列前的最小等待时间)、重试时间(设置消息何时重新排队)、过期时间(设置何时删除消息)。


需要注意的是,Disque项目尚处于Alpha预览测试阶段,代码和算法未经充分测试,还不适合用于生产环境。在接下来的几个月里,其实现和API很可能会发生重大变化。此外,它还有如下限制:

其中还包含许多没有用到的Redis代码;


它并非源于Salvatore的项目需求,而是源于他看到人们将Redis用作队列,但他不是这方面的专家;


同Redis一样,它是单线程的,但鉴于它所操作的数据结构并不复杂,将来可以考虑改为多线程;


Disque进程中的作业数量受可用内存限制;


Disque没有进行性能优化。


总之,该项目尚处于研究测试阶段。感兴趣的读者可以点击“阅读原文”查看该项目的GitHub页面,了解更多信息



回复关键词查看对应内容:

React | 架构师 | 运维 | 云 | 开源 | Kubernetes | 架构 | 人工智能 | Kafka | Docker | Netty | CoreOS | QCon | Github | Swift | 敏捷 | 语言 | 程序员 | 实践 | 物联网 |





 
InfoQ 更多文章 Facebook如何实现PB级别数据库自动化备份 学术派Google软件工程师Matt Welsh谈移动开发趋势 Spotify为什么要使用一些“无聊”的技术? 妹纸们放假了,汉纸们做啥? 大多数重构可以避免
猜您喜欢 培训的程序员“差”在哪? php缓存技术总结 【原译】webpack 2和babel 6的tree-shaking [连载] 途客们的旅行梦 - 苦中求乐 iOS8性能测试:苹果有多爱HTML5