秒杀设计思路

本文讨论了在高并发秒杀中如何通过削峰限流、异步处理和Redis的使用来管理库存,确保原子性和减少超卖。同时提到使用Redis和消息队列的优缺点,以及如何通过Redis实现简单消息队列功能。
摘要由CSDN通过智能技术生成

高并发

秒杀环节会一瞬间涌入大量需求,主要思路就是削峰、限流、异步、补偿。
异步这里可以用消息队列来实现。将抢(即排队点进去跳转到wx或者zfb付款界面)还有购(就是真正支付的时候)分开,这样可以为mysql减压。
抢可以用redis来做,毕竟它轻量级,一秒能写入10w,并且可以集群提高扩展能力。可以先将库存数量加载到redis,然后在redis里扣减,扣减成功的消息传给消息队列。最后mysql从消息队列取消息来做真正的订单生产。
再说如何提升redis处理请求能力,假设我们预估一秒来的请求超过6w(毕竟要给redis留点余量,不能顶满),那可以考虑用多个redis分流。比如预计1s来了100w请求,那就把库存余额平均分20个redis,就可以处理了。然后来一个请求随机分给这20个里的任意一个,你分到的redis已经没余额就只能怪自己人品差了。

防止超卖

这个就是考察如何用redis保证原子性。可以判断余额和扣减库存两者写到一个Lua脚本里。这样的话有三种情况:

  • 正常运行,发现库存用完了,那直接告诉用户没了就行
  • 访问redis错误,也直接告诉用户让他刷新重试一下就行
  • 访问redis超时(也就是网络错误之类的),其实这个时候可能已经扣完库存量了,不用重试了,因为是无效扣减,也就是说总数是不变的,只不过这一次扣减没让任何一个用户抢到东西而已,大不了少卖了。

尽可能避免少卖

除了超卖里第三条外,redis向消息队列发送信息出错误的话也会引起少卖现象。解决方案有三种:

  • 发送给消息队列失败的话,会返回报错,只要增加渐进式重试机制就行(隔1s、5s、30s、1min…再重试一下),这种机制而不是固定时间轮询是因为失败一次大概率还会失败,所以节约cpu
  • 更安全的方法,在第一种的基础上把消息记录在磁盘上
  • 写磁盘也可能失败,但是再走WAL那套日志就和mysql的binlog、redolog之类差不多了,太复杂了没必要

所以实际上用第二种就行,大不了人工介入补偿一下,比如二次余量销售

Redis角色

redis能扮演扣减库存的角色主要是因为比sql处理能力强太多。实际上消息队列也可以只用redis代替,只不过不怎么可靠。后面补一下具体消息队列知识(kafka、rocketMQ之类的)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值