最近看了Dyno-queues分布式延迟队列的源码,发现了一些不错的技巧,而本文是对Dyno-queues架构精华的总结。 本文是根据 https://medium.com/netflix-techblog/distributed-delay-queues-based-on-dynomite-6b31eca37fbc 翻译而来,如果有不准之处请大家多包含。
在Netflix的平台上运行着许多的业务流程,这些流程的任务是通过异步编排进行驱动,现在我们要实现一个分布式延迟队列,这个延迟队列具有如下特点:
Dynomite是一种通用的实现,可以与许多不同的key-value存储引擎一起使用。目前它提供了对Redis序列化协议(RESP)和Memcached写协议的支持。我们选择Dynomite,是因为其具有性能,多数据中心复制和高可用性的特点。此外,Dynomite提供分片和可插拔的数据存储引擎,允许我们在数据需求增加垂直和水平扩展。
我们选择Redis作为构建队列的存储引擎:
一个队列被存储为Redis的有序集合(ZADD和ZRANGE等操作),Redis使用分数对有序集合中的成员进行排序,当往队列中存储数据时,根据优先级和超时时间计算分数。
对于每个队列,维护三组Redis数据结构:
PUSH
POP
ACK
我们的队列是在Dynomite的JAVA客户端Dyno之上建立的,Dyno为持久连接提供连接池,并且可以配置为拓扑感知,此外,Dyno为应用程序提供特定的本地机架(在AWS中,机架是一个区域,例如 us-east-1a、us-east-1b等),us-east-1a的客户端将连接到相同区域的Dynomite/Redis节点,除非该节点不可用,在这种情况下该客户端将进行故障转移。这个属性被用于通过区域划分队列。
分片 队列根据可用区域进行分片,将数据推送到队列时,通过轮训机制确定分片,这种机制可以确保所有分片的数据是平衡的,每个分片都代表Redis中的有序集合,有序集中的key是queueName和AVAILABILITY _ZONE的组合。
避免全局锁
image.png
处理Un-ACK的消息 后台进程监视UNACK集合中的消息,这些消息在给定时间内未被客户端确认(每个队列可配置)。这些消息将移回到队列中。
Dyno-queues分布式延迟队列的github地址是: https://github.com/Netflix/dyno-queues