1. 引言
1.1 消费队列
这天,小❤在购买火车票时,发现如果存在一个未支付的订单时,就不能再进行购票了。如果把待支付的订单放在一个队列里面,那么队列的长度就只能是 1.
正好最近用 Redis 比较多,于是,我突发奇想,如何用 Redis 原生的数据结构实现一个简易版的延时消费队列呢?
业务状态图如下:
并且,需要保证队列的长度是可控的,比如,我们只允许用户有 3 个未支付的订单。
1.2 Redis实现
Redis,作为一款高性能的缓存和数据存储数据库,一直以来都是后台开发者的得力助手。
如果用 Redis 作为消费队列,那么我们可以用到的数据结构有:List、Hash 和 Set。在上述的业务场景中,由于我们只需要关注 orderId
(订单 ID),因此这三个数据结构都是可用的。
比如,用 hash
来存储时,我们可以将 key 设置为 UnpaidOrder-{userId}
,每个 field 都是一个订单。
但是,我们现在面临一个挑战:每个订单的存活时长是不同的,分为手动消费和定期删除的逻辑。
- 订单 1 手动支付后,需要将 orderId1 从列表中删除
- 订单 2 在半小时内还未支付,就自动过期,用户还可以继续提交订单到未支付状态
所以在 List、Set 或者 Hash 结构中,每个 field 都需要设置单独的过期时间。
这是一个常见而又棘手的问题,本文将从互联网业务中常见的解决方案入手,来深入探讨一下 Redis 的底层实现。
2. 常见方案
在实际业务中,我们经常会遇到这样的场景:需要统计某些字段的个数,并且这些字段的过期时间各有先后。
就上