3万个商品高并发下秒杀有什么方案实现超卖、少卖

昵称就这么定了 2016-05-18 09:52:22
现有3万个商品秒杀,公司以及下层多级渠道各自设定3万个商品的库存,用户购买商品的数量不能多于公司及渠道加起来的库存,要求10秒内返回秒杀结果。
目前想到方案:每个用户购买时都添加到redis队列进行排队,并行改成串联方式,购买成功即对商品进行-1操作,但是这样有个弊端是处理队列不及时造成用户等待返回结果过长。
大家有什么秒杀的方案,讨论一下
...全文
15983 13 打赏 收藏 转发到动态 举报
写回复
用AI写文章
13 条回复
切换为时间正序
请发表友善的回复…
发表回复
yeyingwulh 2017-08-04
  • 打赏
  • 举报
回复
(非原创) 1. 尽量将请求拦截在系统上游: 2. 读多写少,多使用缓存 • 浏览器和app:做限速,限制用户在X秒之内只能提交一次请求(比如虽然你在疯狂的摇微信,但其实x秒后才向后端发起一次请求) • 站点层:按照uid做限速,做页面缓存,这时用uid,一个uid5秒只准透过一个请求。这样就能拦住99%的for循环请求。 • 服务层:按照业务做写请求队列控制流量(每个提供服务的服务器各一个队列)(每次只透有限的写请求去数据层,如下订单,做支付这样的写业务)。3k张火车票,只透3k个下单去db • 数据层:这时已经没有多少压力了。全部透到数据库,100w个下单,0个成功,请求有效率是0%;透3k个请求到数据,全部成功,请求有效率100%
huapox 2016-06-30
  • 打赏
  • 举报
回复
若用悲观锁,不要用在db层,应用在cache层: 不建议在数据库层面加锁,建议通过服务端的内存锁(锁主键)。当某个用户要修改某个id的数据时,把要修改的id存入memcache,若其他用户触发修改此id的数据时,读到memcache有这个id的值时,就阻止那个用户修改。
huapox 2016-06-30
  • 打赏
  • 举报
回复
建议用乐观锁, 并发 一致性问题参考: 秒杀系统:并发队列 接口设计 并发请求数据安全处理 http://www.xue163.com/2253/1/22530718.html
  • 打赏
  • 举报
回复
引用 1 楼 starfd 的回复:
用消息队列 客户消费时就是发送消息,然后等待消息响应,因为你可以接受的等待时间长达10秒,所以完全无压力 至于数据一致性,直接用数据库锁应该也可以达到你的并发请求了,完全没必要全部走串行的方式
用户同时可以购买10000个商品,目前的做法是先读出来这10000个商品的库存,然后计算再入库,数据库锁实现不了
  • 打赏
  • 举报
回复
引用 2 楼 xuanbg 的回复:
根本不需要减库存,只需要按时间给出秒杀有效还是无效就行了。超卖是不会的,少卖在付款有效期限内是避免不了的。方法很简单,人家秒杀时候不需要判断有没有库存,只管把数据保存起来。过一段时间,譬如8秒,如果库存是10个,就取前10条记录,把秒杀结果状态字段更新成秒杀成功,然后前端在10秒后读取这个状态就可以了。
需求类似秒杀但不限时,目的就是让商品不超卖,目前的方案就有点像你说的,用户购买后检查库存是否满足,不满足就标记当前用户购买失败,这种方案是每个用户都检查一遍,比较耗时
software_artisan 2016-05-18
  • 打赏
  • 举报
回复
根本不需要减库存,只需要按时间给出秒杀有效还是无效就行了。超卖是不会的,少卖在付款有效期限内是避免不了的。方法很简单,人家秒杀时候不需要判断有没有库存,只管把数据保存起来。过一段时间,譬如8秒,如果库存是10个,就取前10条记录,把秒杀结果状态字段更新成秒杀成功,然后前端在10秒后读取这个状态就可以了。
  • 打赏
  • 举报
回复
用消息队列 客户消费时就是发送消息,然后等待消息响应,因为你可以接受的等待时间长达10秒,所以完全无压力 至于数据一致性,直接用数据库锁应该也可以达到你的并发请求了,完全没必要全部走串行的方式
  • 打赏
  • 举报
回复
引用 9 楼 sp1234 的回复:
那些费时间、让服务器系统崩溃的做法,都是因为纠结所谓的“数据库事务”而坑爹的。

你只要跟数据库事务分道扬镳,将长事务分离开,就能保证每秒处理10万笔以上业务。完全没有压力,处理秒杀很简单。

实质上把秒杀单独做一个简单的只有几十行代码的通用进程,就可以了。


不太明白你的方案,能否对以下是渠道架构及问题给一个详细一点的方案
公司
A1 A2
B1 B2 B3 B4
C1, C2 C3, C4 C5,C6 C7,C8
用户活跃数2000以下
比如30000商品中的P9手机,在公司-A1-B1-C1渠道设定一个1000的数组,在这么多渠道下一个商品岂不是设定N个数组?
想象一下一个商品N个数组,30000个商品是多少个数组
  • 打赏
  • 举报
回复
那些费时间、让服务器系统崩溃的做法,都是因为纠结所谓的“数据库事务”而坑爹的。 你只要跟数据库事务分道扬镳,将长事务分离开,就能保证每秒处理10万笔以上业务。完全没有压力,处理秒杀很简单。 实质上把秒杀单独做一个简单的只有几十行代码的通用进程,就可以了。
  • 打赏
  • 举报
回复
引用 3 楼 jian_en 的回复:
[quote=引用 2 楼 xuanbg 的回复:] 根本不需要减库存,只需要按时间给出秒杀有效还是无效就行了。超卖是不会的,少卖在付款有效期限内是避免不了的。方法很简单,人家秒杀时候不需要判断有没有库存,只管把数据保存起来。过一段时间,譬如8秒,如果库存是10个,就取前10条记录,把秒杀结果状态字段更新成秒杀成功,然后前端在10秒后读取这个状态就可以了。
需求类似秒杀但不限时,目的就是让商品不超卖,目前的方案就有点像你说的,用户购买后检查库存是否满足,不满足就标记当前用户购买失败,这种方案是每个用户都检查一遍,比较耗时[/quote] 你没有看懂 #2 楼所说的。 #2 楼说的是“不需要判断有没有库存”,也就是说在整个跟库存有关的长时间操作中都没有加锁。 你可以把描述商品作为“单品”取出来,在秒杀时减这个单独的数字。比如说有1000部P9手机,那么就初始化一个1000个单元的数组,没一个数组单元都是放置“交易号”。当秒杀时,就是为这个数组顺序填写交易号(近几年在这个瞬间的操作需要lock而已,因此每秒可以处理50完毕交易),直到数组单元被填满为止。 而至于说每一个交易用1秒还是1小时完成,那就跟这个数组没有关系。也就是说跟秒杀没有关系。
  • 打赏
  • 举报
回复
近几年在这个瞬间的操作需要lock而已 --> 仅仅在这个瞬间的操作需要lock而已 其实秒杀操作,关键就是要把秒杀数据结构跟库存分离。就这么简单。
风吹腚腚凉 2016-05-18
  • 打赏
  • 举报
回复
我给的建议是, 先生成3W条数据加载到内存中去,用户秒杀一次直接从内存读数据,然后更新数据库,数据库那边可以用队列更新。 慢慢来。 当然你的服务器应该承载不了这么大的数据量,你还要用分布式系统,每秒30W+的数据量还是很恐怖的。
风吹腚腚凉 2016-05-18
  • 打赏
  • 举报
回复
引用 1 楼 starfd 的回复:
用消息队列 客户消费时就是发送消息,然后等待消息响应,因为你可以接受的等待时间长达10秒,所以完全无压力 至于数据一致性,直接用数据库锁应该也可以达到你的并发请求了,完全没必要全部走串行的方式
如果用数据库锁的话,你数据库连接池的连接都不够用。

13,190

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 分析与设计
社区管理员
  • 分析与设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧