我正在开发一个我认为需要队列的应用程序。我已经打算在应用程序中使用Redis Enterprise,因此将Redis用于队列是有意义的。 Redis为队列提供了一些有用的命令:https://redis.io/commands/rpoplpush#pattern-reliable-queue。我有生成器插入记录和消费者处理和删除记录。我可以轻松地让生产者和消费者横向扩展。因此,在规模上,瓶颈将是Redis,因为队列只能存储在单个分片上。是否有一种跨多个分片分配队列的好方法?我能想出的唯一解决方案是创建多个队列,并以某种方式确保每个队列哈希到不同的分片。但是,当Redis被重新分配时,这将需要更改生产者,消费者和队列密钥,这不是理想的。
我打算使用队列批量将记录插入数据库。生产者是接收请求和生成记录的Web服务器。但在高峰流量时,数据库将无法跟上单行插入的速度。我无法在Web服务器上缓冲请求,因为当Web服务器出现故障时,所有缓冲的记录都将丢失。由于复制,Redis队列提供容错功能。在执行插入之前,消费者可以从队列中弹出多个记录以减轻数据库的负载。但它没有足够的规模。我缺少一个更好的Redis解决方案吗?或者Redis不适合?
非常感谢任何建议!
修改
我已经开始使用@Itamar Haber讨论的方法创建一个库。可在此处获取:https://github.com/fenichelar/BQueue
答案 0 :(得分:2)
单个Redis数据结构(例如List)确实无法分片。需要提出的第一个问题是您的扩展问题是否合理 - 如果不是100s的1000s操作/秒,单个Redis分片可以轻松执行10s,并且这种吞吐量可以有很长的路要走。
假设单个键/数据结构/分片不足以满足您的需求(吞吐量方面),您可以采用多个键来实现水平扩展。
以某种方式确保每个队列哈希到不同的分片
实际上,它过分了一点IMO。默认的散列函数通常足够好,所以如果你选择一个合理数量的键/队列(例如10或42),你很可能会在各个插槽中得到这些密码/队列。
但是当Redis重新分区时,这将需要更改生产者,消费者和队列密钥,这不是理想的。
我不同意。首先,您需要记住,特别是重新分片和一般情况下集群拓扑发生了变化,这种情况非常罕见。我并不是说它们不会发生,但它们通常是由人们策划和管理的。其次,更重要的是,即使发生了这样的更改并且散列槽穿过分片,所有/大多数/许多队列在同一节点上结束的可能性仍然很低(见上文)。最后,如果您的所有密钥确实在一个分片上结束,您可以随后手动重新洗牌/迁移它们以平衡负载(使用Redis Enterprise的UI / CLI / API非常容易)。
最重要的是,您无需更改密钥名称,生产者和/或消费者。
意见:我认为Redis非常适合在另一个数据库/存储器前面的更新缓冲区,它更慢,无法处理峰值。
免责声明:我在Redis Labs工作,Redis Labs是开源Redis的所在地,也是Redis Enterprise的提供商。