Redis Enterprise(分片)可靠队列
Redis Enterprise (sharding) reliable queue
我正在开发一个我认为需要队列的应用程序。我已经打算在应用程序中使用 Redis Enterprise,因此将 Redis 用于队列是有意义的。 Redis 有一些有用的队列命令:https://redis.io/commands/rpoplpush#pattern-reliable-queue。我有插入记录的生产者和处理和删除记录的消费者。我可以很容易地让生产者和消费者横向扩展。因此,在规模上瓶颈将是 Redis,因为队列只能存储在单个分片上。有没有一种跨多个分片分布队列的好方法?我能想到的唯一解决方案是创建多个队列,并以某种方式确保每个队列散列到不同的分片。但这需要在 Redis 重新分片时更改生产者、消费者和队列键,这并不理想。
我打算使用队列将记录批量插入数据库。生产者是接收请求并生成记录的网络服务器。但是在高峰流量期间,数据库将无法跟上单行插入的速度。我不能只缓冲 Web 服务器上的请求,因为当 Web 服务器发生故障时,所有缓冲的记录都会丢失。由于复制,Redis 队列提供了容错能力。消费者可以在执行插入之前从队列中弹出多条记录,以减轻数据库的负载。但它的规模不够大。我缺少更好的 Redis 解决方案吗?还是 Redis 不合适?
如有任何建议,我们将不胜感激!
编辑:
我已经开始使用与@Itamar Haber 讨论的方法创建一个库。此处可用:https://github.com/fenichelar/BQueue
单个Redis数据结构,比如List,确实不能分片。需要问的第一个问题是您的扩展问题是否合理 - 单个 Redis 分片可以轻松执行 10 秒,如果不是 100 秒或 1000 秒 ops/sec,并且这种吞吐量可以走很长一段路。
假设单个 key/data structure/shard 不足以(吞吐量方面)满足您的需求,使用多个键的直觉确实是横向扩展的方式。
somehow ensure each queue hashes to a different shard
实际上,在我看来,这有点过头了。默认的散列函数通常已经足够好了,所以如果您选择合理数量的 keys/queues(例如 10 或 42),您很可能会在槽中获得这些值的可靠分布。
But this would require the producers, consumers, and queue keys to be changed when Redis is resharded which isn't ideal.
我不同意。首先,您需要记住,特别是重新分片和集群拓扑结构的更改通常是非常罕见的。我并不是说它们不会发生,但它们通常是由人计划和管理的。其次,更重要的是,即使发生了此类更改并且哈希槽在分片之间穿梭,all/most/many 队列在同一节点上结束的可能性仍然非常低(见上文)。最后,如果你的所有键确实都在一个分片上,你总是可以在之后手动 reshuffle/migrate 它们以平衡负载(使用 Redis Enterprise 的 UI/CLI/API 非常容易)。
最重要的是,生产者,您无需更改密钥名称 and/consumers。
意见:我认为 Redis 非常适合在另一个速度较慢且无法处理峰值的 db/storage 之前用作更新缓冲区。
免责声明:我在 Redis Labs 工作,这里是开源 Redis 的发源地和 Redis Enterprise 的提供商。
我正在开发一个我认为需要队列的应用程序。我已经打算在应用程序中使用 Redis Enterprise,因此将 Redis 用于队列是有意义的。 Redis 有一些有用的队列命令:https://redis.io/commands/rpoplpush#pattern-reliable-queue。我有插入记录的生产者和处理和删除记录的消费者。我可以很容易地让生产者和消费者横向扩展。因此,在规模上瓶颈将是 Redis,因为队列只能存储在单个分片上。有没有一种跨多个分片分布队列的好方法?我能想到的唯一解决方案是创建多个队列,并以某种方式确保每个队列散列到不同的分片。但这需要在 Redis 重新分片时更改生产者、消费者和队列键,这并不理想。
我打算使用队列将记录批量插入数据库。生产者是接收请求并生成记录的网络服务器。但是在高峰流量期间,数据库将无法跟上单行插入的速度。我不能只缓冲 Web 服务器上的请求,因为当 Web 服务器发生故障时,所有缓冲的记录都会丢失。由于复制,Redis 队列提供了容错能力。消费者可以在执行插入之前从队列中弹出多条记录,以减轻数据库的负载。但它的规模不够大。我缺少更好的 Redis 解决方案吗?还是 Redis 不合适?
如有任何建议,我们将不胜感激!
编辑:
我已经开始使用与@Itamar Haber 讨论的方法创建一个库。此处可用:https://github.com/fenichelar/BQueue
单个Redis数据结构,比如List,确实不能分片。需要问的第一个问题是您的扩展问题是否合理 - 单个 Redis 分片可以轻松执行 10 秒,如果不是 100 秒或 1000 秒 ops/sec,并且这种吞吐量可以走很长一段路。
假设单个 key/data structure/shard 不足以(吞吐量方面)满足您的需求,使用多个键的直觉确实是横向扩展的方式。
somehow ensure each queue hashes to a different shard
实际上,在我看来,这有点过头了。默认的散列函数通常已经足够好了,所以如果您选择合理数量的 keys/queues(例如 10 或 42),您很可能会在槽中获得这些值的可靠分布。
But this would require the producers, consumers, and queue keys to be changed when Redis is resharded which isn't ideal.
我不同意。首先,您需要记住,特别是重新分片和集群拓扑结构的更改通常是非常罕见的。我并不是说它们不会发生,但它们通常是由人计划和管理的。其次,更重要的是,即使发生了此类更改并且哈希槽在分片之间穿梭,all/most/many 队列在同一节点上结束的可能性仍然非常低(见上文)。最后,如果你的所有键确实都在一个分片上,你总是可以在之后手动 reshuffle/migrate 它们以平衡负载(使用 Redis Enterprise 的 UI/CLI/API 非常容易)。
最重要的是,生产者,您无需更改密钥名称 and/consumers。
意见:我认为 Redis 非常适合在另一个速度较慢且无法处理峰值的 db/storage 之前用作更新缓冲区。
免责声明:我在 Redis Labs 工作,这里是开源 Redis 的发源地和 Redis Enterprise 的提供商。