电商红包雨是如何实现的?拿去面试用(典型高并发)

本文介绍了电商红包雨的实现原理,重点探讨了基于Redis和Lua脚本的高并发解决方案。文章详细阐述了整体流程、红包的Redis设计、事务原理及其ACID特性,特别是Lua脚本在确保原子性和隔离性方面的作用。通过Lua脚本,减少了网络开销并实现了原子操作,是应对抢红包这类高并发场景的理想选择。
摘要由CSDN通过智能技术生成

想必大家应该都点过红包雨,就是各大电商大促时候都会搞的那个活动。

那具体如何实现红包雨的功能呢?我们来看下勇哥的分享。

我服务的一家电商公司也加入了这次热潮,技术团队研发了直播答题功能。答题结束之后,红包会以红包雨的形式落下,用户点击屏幕上落下的红包,若抢到红包,红包会以现金的形式进入用户账户。

红包雨是一个典型的高并发场景,短时间内有海量请求访问服务端,技术团队为了让系统运行顺畅,抢红包采用了基于 Redis + Lua 脚本的设计方案。

1 整体流程

我们分析下抢红包的整体流程 :

  1. 运营系统配置红包雨活动总金额以及红包个数,提前计算出各个红包的金额并存储到 Redis 中;

  2. 抢红包雨界面,用户点击屏幕上落下的红包,发起抢红包请求;

  3. TCP 网关接收抢红包请求后,调用答题系统抢红包 dubbo 服务,抢红包服务本质上就是执行 Lua 脚本,将结果通过 TCP 网关返回给前端;

  4. 用户若抢到红包,异步任务会从 Redis 中 获取抢得的红包信息,调用余额系统,将金额返回到用户账户。

2 红包 Redis 设计

抢红包有如下规则:

  • 同一活动,用户只能抢红包一次 ;

  • 红包数量有限,一个红包只能被一个用户抢到。

如下图,我们设计三种数据类型:

  1. 运营预分配红包列表 ;

队列元素 json 数据格式 :

{
    //红包编号
    redPacketId : '365628617880842241' 
    //红包金额
    amount : '12.21'          
}
  1. 用户红包领取记录列表;

队列元素 json 数据格式:

{
    //红包编号
    redPacketId : '365628617880842241'
    //红包金额
    amount : '12.21',
    //用户编号
    userId : '265628617882842248'
}
  1. 用户红包防重 Hash 表;

抢红包 Redis 操作流程 :

  1. 通过 hexist 命令判断红包领取记录防重 Hash 表中用户是否领取过红包 ,若用户未领取过红包,流程继续;

  2. 从运营预分配红包列表 rpop 出一条红包数据 ;

  3. 操作红包领取记录防重 Hash 表 ,调用 HSET 命令存储用户领取记录;

  4. 将红包领取信息 lpush 进入用户红包领取记录列表。

抢红包的过程 ,需要重点关注如下几点 :

  • 执行多个命令,是否可以保证原子性 ,  若一个命令执行失败,是否可以回滚;

  • 在执行过程中,高并发场景下,是否可以保持隔离性;

  • 后面的步骤依赖前面步骤的结果。

Redis 支持两种模式 :  事务模式 和 Lua 脚本,接下来,我们一一展开。

3 事务原理

Redis 的事务包含如下命令:

序号 命令及描述
1 MULTI 标记一个事务块的开始。
2 EXEC 执行所有事务块内的命令。
3 DISCARD 取消事务,放弃执行事务块内的所有命令。
4 WATCH key [key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。
5 UNWATCH 取消 WATCH 命令对所有 key 的监视。

事务包含三个阶段:

  1. 事务开启,使用 MULTI , 该命令标志着执行该命令的客户端从非事务状态切换至事务状态 ;

  2. 命令入队,MULTI 开启事务之后,客户端的命令并不会被立即执行,而是放入一个事务队列 ;

  3. 执行事务或者丢弃。如果收到 EXEC 的命令,事务队列里的命令将会被执行 ,如果是 DISCARD 则事务被丢弃。

下面展示一个事务的例子。

redis> MULTI 
OK
redis> SET msg "hello world"
QUEUED
redis> GET msg
QUEUED
redis> EXEC
1) OK
1) hello world

这里有一个疑问?在开启事务的时候,Redis key 可以被修改吗?

在事务执行 EXEC 命令之前 ,Redis key 依然可以被修改

在事务开启之前,我们可以 watch 命令监听 Redis key 。在事务执行之前,我们修改 key 值 ,事务执行失败,返回 nil 。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值