秒杀系统设计与思考

秒杀系统要解决什么

  1. 削峰填谷,将大批量的请求分批流向DB,避免DB被冲垮
  2. 兼顾性能的同时,保证下单时查验库存与扣减库存的原子性,避免超卖少卖问题
  3. 隔离资源,限流,保护除了秒杀系统外的其他系统正常运行。

秒杀系统怎么设计

前期准备

  1. 前端防刷。减少用户频繁点击带来的不必要流量。
  2. 网关限流。根据IP进行限流,阻挡黄牛和恶意用户。

技术选型

  1. 消息中间件,主要用于削峰填谷,主流的kafka、rabbitmq、rocketmq皆可。我这边选我自己比较熟悉的rabbitmq,实测单机可达10000TPS,可满足绝大多少场景。
  2. 库存采用Redis,redis本身对请求保证原子性,利用lua脚本可以同时进行校验库存和扣减库存两步操作
  3. 数据库依旧使用Mysql,做好分库分表提高写入速率。可以按用户纬度进行分库,将写入的负责分摊到不同数据库中。
    流程设计

在这里插入图片描述

主要由以下三步构成:

  1. 秒杀参与接口。
    检验活动、用户限购、库存之后,将请求打包、生成唯一的traceId,然后放入MQ中。返回traceId给客户端
  2. 订单消费者。
    从MQ中消费秒杀下单请求,利用redis+lua保证原子性,同时原子的执行校验库存、扣减库存后,完成下单,并在redis中缓存下单结果
  3. 订单轮询接口。
    客户端轮询获取下单结果。

问题1:
如何保证不超卖?

利用redis+lua保证原子性,在下单前,原子性的完成库存校验和扣减。

问题2:
如何保证不少卖?

利用两阶段提交。具体流程如下

  1. begin。在校验和扣减库存的lua脚本中,利用zset 记录一行数据 (value=订单号,score=当前时间+5分钟)。
  2. commit。下单成功后执行,lua脚本实现,删除zset中 (value=订单号,score=当前时间+5分钟)这个行数据
  3. rollback。下单失败执行,lua脚本实现,删除zset中 (value=订单号,score=当前时间+5分钟)这个行数据,并且补回库存。
  4. 在定时器中,利用zrangebyscore取出订单号,检查是否下单成功,下单成功则删除改行,下单失败则补回库存后删除该行。

魏王待续

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值