秒杀系统主要需要考虑的问题
- 优化用户体验,提升用户打开页面的速度。
- 降低服务器的压力,提高系统的并发处理能力。
- 减少数据库访问次数。
- 利用缓存技术提升系统的响应速度。
- 防止超卖。
秒杀系统架构设计
- 将秒杀活动相关信息写入静态文件,通过CDN加速,提高秒杀活动页面的打开速度,降低web服务器的压力。
- 将商品库存数量缓存到redis,减少数据库的访问。
- 使用redis原子性操作[decr],控制超卖问题。
- 通过MQ队列,异步生成订单。
- 数据库扣减库存,采用行锁,减少锁定数据的范围。
遗留问题
当订单创建成功后,用户放弃支付,库存数量怎么回收?
- 是否可以通过redis的incr操作,将取消订单中的商品数量加回到库存中呢?
redis的decr操作,对缓存值-1,再返回最新值。比如:缓存值是100,访问150次,那当前的缓存就是-50了,所以在取消订单时,通过incr操作显示是不行的。
- 是否可以在取消订单时,通知redis缓存从数据库更新库存数据呢?
这个方案是可以拿到最新的库存,但是这个过程必须要加锁,且是必须是分布式锁。加锁必然会影响性能。
我说一下针对这个问题,我的解决思路是:
- 订单取消时,返还库存,采用行锁,保证库存操作的原子性。
- 在redis中缓存两个数据,一个是当前库存数量(key:stock_1),另一个是前一个缓存的key(key:stock_key),即value:stock_1。
- 创建定时任务,每隔10分钟查询是否存在新取消的订单,如果存在,则通过get命令查询redis中缓存的库存数量是否小于等于0(为什么要redis缓存的库存数量小于等于0才执行呢?因为要避免加锁)。
- 若这两个条件都成立,则从数据库查询最新商品库存数量(行锁),使用一个新key(比如:stock_2)将库存数量写入redis中,更新redis中库存key的值为stock_2。这样其它用户下单时,就能访问到被释放的库存数量了。
最后,需要注意订单支付与订单取消异步的问题。
本文暂时没有评论,来添加一个吧(●'◡'●)