- 功能核心点
* 经典互联网商品抢购秒杀功能
- 功能api
* 商品秒杀接口
- 数据落地存储方案
* 通过分布式redis减库存
* DB存最终订单信息数据
- api性能调优
* 性能瓶颈在高并发秒杀
* 技术难题在于超卖问题
秒杀系统功能步骤梳理
- 利用 Redis 缓存incr拦截流量
- 首先通过数据控制模块,提前将秒杀商品缓存到读写分离 Redis,并设置秒杀开始标记如下:
"skuId_start": 0 //开始标记1表示秒杀开始
"skuId_count": 10000 //总数
"skuId_access": 12000 //接受抢购数(接受最大抢购数=1.2*商品总数)
- 秒杀开始前,服务集群读取 skuId_start为 0,直接返回未开始。
- 服务时间不一致可能导致流量倾斜
- 数据控制模块将 skuId_start 改为1,标志秒杀开始。
- 当接受下单数达到 sku_count*1.2 后,继续拦截所有请求,商品剩余数量为 0
- 利用Redis缓存加速库存扣量
"skuId_booked": 10000 //总数0开始10000 通过incr扣减库存,返回抢购成功
- 将用户订单数据写入mq
- 监听mq入库
秒杀系统功能api实战(上)
** 后端秒杀网关流量拦截层功能开发 **
- 先判断秒杀是否已经开始
* 初始化时将key:skuId_start_1 value:0_1554046102存入数据库中
- 利用 Redis 缓存incr拦截流量
- 缓存拦截流量代码编写
- 用incr方法原子加
- 通过原子加判断当前skuId_access是否达到最大值
- 思考:是否需要保证获取到值的时候和incr值两个命令的原子性
* 保证原子性的方式,采用lua脚本
* 采用lua脚本方式保证原子性带来缺点,性能有所下降
* 不保证原子性缺点,放入请求量可能大于skuId_access
秒杀系统功能api实战(中)
** 后端秒杀信息校验层功能开发布隆过滤器实现重复购买拦截 **
- 订单信息校验层
* 校验当前用户是否已经买过这个商品
- 需要存储用户的uid
- 存数据库效率太低
- 存Redis value方式数据太大
- 存布隆过滤器性能高且数据量小
- 校验完通过直接返回抢购成功
秒杀系统功能api实战(下)
** 后端秒杀信息校验层功能开发lua脚本实现库存扣除**
- 库存扣除成功,获取当前最新库存
- 如果库存大于0,即马上进行库存扣除,并且访问抢购成功给用户
- 考虑原子性问题
* 保证原子性的方式,采用lua脚本
* 采用lua脚本方式保证原子性带来缺点,性能有所下降
* 不保证原子性缺点,放入请求量可能大于预期值
* 当前扣除库存场景必须保证原子性,否则会导致超卖
- 返回抢购结果
* 抢购成功
* 库存没了 ,抢购失败
初始化库存数据: