使用Redis List作为红包队列,结合Lua脚本原子操作实现抢红包逻辑,确保性能稳定、秒级到账。
方案一:基础List队列抢红包
网友分享:用RPOPLPUSH命令实现红包原子领取,先从source list弹出,再推到used list,避免重复领取。代码:redis.eval("if redis.call('llen', KEYS[1]) > 0 then redis.call('rpoplpush', KEYS[1], KEYS[2]) return 1 else return 0 end", 2, 'redpacket_queue', 'used_queue')。测试并发1万QPS,延迟<10ms,超级稳。
方案二:分数排序+原子扣减
一个大佬推荐:Redis ZSet存红包金额,总额用String记录。抢红包Lua脚本:检查ZSet大小>0,取出最小分数pop,原子扣总金额。脚本:local total = redis.call('get', KEYS[3]); if #redis.call('zrange', KEYS[1], 0, 0, 'WITHSCORES') > 0 and tonumber(redis.call('get', KEYS[3])) > 0 then local val = redis.call('zpopmin', KEYS[1])[2]; redis.call('decrby', KEYS[3], val); return val; end return nil。秒杀场景完美,QPS破10万。
方案三:HyperLogLog防刷+Stream
网友经验:用Redis Stream作为队列,XREADGROUP消费组实现分布式抢,结合HyperLogLog统计用户唯一性防刷。配置:XGROUP CREATE stream group1 $ MKSTREAM,然后消费者XREADGROUP。性能稳定,红包秒到账,还防作弊。实测双11峰值无压力。
方案四:Ring队列优化
分享:自定义Ring Buffer队列,用两个List互换head tail,LPUSH RPOP循环。Lua封装:if list_len(head) == 0 then swap head tail; end rpop head。内存利用率100%,并发无锁,红包发放如丝般顺滑,延迟1ms内。
方案五:多队列分片
高并发方案:按用户ID哈希分16个队列,Lua SELECT db + RPOP。客户端轮询队列或用PubSub通知。网友测试:单机50万QPS,红包瞬间到手,稳定性拉满。
方案六:哨兵+集群扩展
生产环境推荐:Redis Sentinel高可用,Cluster分片队列。抢红包走主节点写,从节点读状态。配置简单,故障秒切换,红包队列永不宕机,秒级到账有保障。
FAQ
Q: 怎么防止用户重复抢同一个红包?
A: 用Lua脚本原子RPOP到used list,一次pop一个,天然防重。
Q: 高并发下Redis会不会卡?
A: 用pipeline批量操作+Lua单次执行,QPS轻松10万+,调大maxmemory。
Q: 红包金额随机怎么实现?
A: ZSet score存随机金额,popmin均匀发;或预生成List存好金额。
Q: 跨机房怎么部署?
A: Redis Cluster跨区分片,主从复制,延迟控制在50ms内,基本秒到账。