讨论数据库减库存几种方法V1

MySQL在电子商务网站使用越来越多,做为第一梯队做MySQL的从业人员,也经常被问到MySQL对于减库存在这块有什么好的处理方法?对于这个问题,想想在课上分享及朋友中交流讲的不下百次。 所以也有了把这个总结一下的想法。
对于减库存的操作,我们需要先从一个更高的Level来看一下,先不用讨论update减1的问题。我们可以把减库存形为简单的分成以下几种:

  • 团购类减库存(库存无限,卖的越多越好) 这个可能大家见的也比较多,就不用多说,这类业务,多卖一些老板反而高兴。
  • 限时活动类(24小时活动产品)
  • 秒杀抢购类活动
  • 正常商品售卖

当然还别的形式,可能有的减订单操作是一个复合型的业务: 如 12306这样的业务,含秒杀,抢购,限时活动于一身,难度空前绝后:)

那么我们再来看一下订单系统里几个难题:
1. 超卖,听说某米是允许在商品接近预警时自动关闭交易(商品下架),并允许一定的超售现象。
2. 羊毛党下单不支付,活动结束,一个也没卖出去。 有的电商的做法是,付款后再减库存,不付款不减,可能出现的问题是,用户犹豫一下,去付款时,告诉你没货了,体验不好。
3. 高并发的抢购,打压到DB中,把DB打死的问题。比较常见的一个问题,早些年某电商还发布过把MySQL死锁去掉的分支,用于支撑抢购里业务,现在MySQL 8.0天生支持,另外也可以考虑在在业务层Nginx上控制。

那么我再回过来看一下减库存的形式,我们可以把减库存,分为两种:

  • 正常商品售卖类减库存
  • 活动促销类减库存

问题分为:是否允许超卖 ,要不要考虑羊毛党的一些形为。 处理好这些问题的情况下支撑高并发业务。另外给老板们提个醒,系统优化是一个全面工作,不只是这里有瓶颈。

我分成几种情况来讨论:

  1. 用户下单减库存 如果允许超卖的情况下, 外加一个预警商品下架(缺货)逻辑来处理,基本可以很快速的跑起来。 业务逻辑最简单适合正常商品逻辑。库存大于多少可以上架之类的一些处理(后台人工调配) 如果不允许超卖, 例如车票这类,处理的办法不在是简单的库存结构设计,可以把每个坐位做为一个商品上架构, 只是车票商品上的属性有自已是那个车,挨着谁之类的信息即可。下单后锁定30分钟… 可以目前各大电商的主流逻辑,只是不同的平台,锁时时间不一样。 防止用户下单后几天后还不支付,让商品可以回归库存,不支付订单的失效过程。 下单减库存也是大家最容易接受的一个形为,但这里把最难的问题抛给了平台,一个商品多少没支付返回库存,目前来看不同平台处理的形为不一样。 不适用于抢购,秒杀点业务。
  2. 支付减库存
    抢购,秒杀,谁先付款谁得的逻辑。 这样可以避免羊毛党下单后不支付的形为,例如,本来只有10个特价产品,羊毛党手快,下单成功,但种种原因没支付,提示商品已售完,但活动结束了,一个商品也没卖出去,老板花的活动费白花了。
  3. 高并发的抢购业务
    例如某米周二中午的抢购,10万个商品,可能是100万人在抢购,这种形为,如果都打到DB,可能是对DB的锁也是一个挑战,可能出现的形为就是不该慢的也慢了,去除检查也是一个好办法。
    现在聪明的人类想好了更好的办法,利用Nginx+LUA引入接入在接层引入摇号方法,基于Cookie在Nginx层拿到了可以购买的资格再往后面放,如果没拿到这个资格就在Nginx上看看,提示你商品已经售完就行。这样每次扩容,只用扩一下Nginx接入层就Ok了,其它不用扩了。

问题分类后,现在来看,对于减库存,如果分类处理后,你会发现,还是挺容易处理的,这里面里也不要再来找我聊用MySQL的乐观锁控制来减库存了,如果你在知数堂的课上学习过,一定会知道多点写入的乐观锁控制会造成更新丢失的现象,同样来讲,单节点的同时并发,不是串行的情况,这事没戏,我确时见过有的公司在这块用了串行事务,他们也跑的挺好,业务量不大。祝你玩的开心。也祝愿你们早日在减库存这块遇到瓶颈,让老板高兴痛苦的给你加薪。

 

作者:吴炳锡 来源:http://wubx.net/ 联系方式: wubingxi#163.com 转载请注明作/译者和出处,并且不能用于商业用途,违者必究.