今天聊聊电商系统中红包活动设计

本文介绍了电商系统中红包活动的设计,重点讲解了基于 Redis 和 Lua 脚本的解决方案。文章详细阐述了抢红包的整体流程、红包的 Redis 设计、事务原理和ACID特性,以及Lua脚本在实现中的作用。通过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'
}` </pre>
  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 。

通过上面的例子,watch 命令可以实现类似乐观锁的效果 。

4 事务的ACID

4.1 原子性

原子性是指:一个事务中的所有操作,或者全部完成,或者全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值