首页 > 其他分享 >实现秒杀的几个想法

实现秒杀的几个想法

时间:2022-12-19 23:02:05浏览次数:36  
标签:剩余 Web 几个 数据库 想法 商品 秒杀 服务器



还是秒杀.

秒杀一般有几个场景

1.电商秒杀商品

2.抢红包

3.抢票


假设一个场景如下:

    某电商公司搞活动,一折秒杀,推出几种秒杀的商品,每种商品1000个,预计100w人抢购

要求:

    不能超卖.绝对不可以卖多了.

    数据库要扣减库存,并且记录订单明细.


难点分析

1.不能阻塞.

海量的请求就像血栓一样,遍走周身,一旦遇到瓶颈,就会堵塞整个血管.

所以一定要让海量的用户请求,尽快结束.


2.数据库单行更新

大量的 update 库存表 set 剩余数量=剩余数量-1 where 商品ID=?

这种单行更新,有行锁,会阻塞其他事务,占用宝贵的数据库处理能力.


针对这种场景,综合了很多资料

我觉得可以尝试几个关于秒杀的优化.




1.Web服务器集群层,卸载流量

    海量的用户秒杀请求,本质上是一个排序,先到先得.

    但是如此之多的请求,完全响应,难度又很大.

    所以在Web服务器集群,可以考虑卸载流量.

    比如每十个请求,随机抛弃九个,只放行一个请求到后续处理环节.

    把秒杀的排序模式,变为随机抽奖的模式.

    

2.Web服务器集群层,缩小锁范围.

    每次秒杀活动开始之前.先计算活动推出的商品数量,然后分配一个限额到每个Web服务器.

    比如一个活动推出秒杀商品

    电视,手机,衣服各1000件,那么每台服务器的限额就是125件.

    将这个限额写入ZooKeeper,Web服务器监听到限额的变化,就会重新初始化各自的商品剩余数量.


模拟示例:

  1.  private static ConcurrentHashMap<String,Integer> map=new ConcurrentHashMap<String, Integer>();
  2.     
  3.     private void zooKeeperHandle(){
  4.         //将ZooKeeper的变化,初始化到Web服务器全局容器
  5.         map.put("电视机", 125);
  6.         map.put("手机", 125);
  7.         map.put("衣服", 125);
  8.     }

    假设用户请求秒杀电视机,它只是锁了该Web服务器电视机的数量。(该Web服务器手机和衣服还可以继续并发处理,当然其他的Web服务器也在同时处理电视机的秒杀请求)

    这样缩小了锁定的范围,增加了系统处理的吞吐量.


    如果这个剩余数量大于零,则将用户ID放入电视机购买队列,然后告知用户秒杀成功

    如果这个剩余数量等于零,则告知用户秒杀失败.即便别的Web服务器还有电视机的剩余配额.


3.ZooKeeper层,ZooKeeper变更库存信息

    假设活动期间,需要修改库存信息。

    两种可能,

    第一种,该商品已经卖了500件,电商不想继续卖了.

    第二种,从仓库中又找到了一些积压库存..


    两种情况,都直接修改ZooKeeper中相应商品的配额.

    Web服务器会监听变化,并重新初始化全局容器.


4.消息队列层,多消费者处理

    消费者主要是从队列获取购买请求,发送至数据库

    扣减数据库库存

    写订单明细记录



5.数据库层,使用存储过程代替JDBC调用

    由于使用了多消费者处理同一队列,增加吞吐量,避免队列堆积过大.

    但是多消费者,必然导致数据库出现单行更新问题.


    单行更新问题就是多个线程,并发修改同一条记录,导致事务相互阻塞.浪费了数据库宝贵的处理能力.

    考查下图.

    假设消费者到数据库的网络是1毫秒

    那么相对于存储过程,使用JDBC的方式,每个事务将至少多持有行锁2毫秒.


    所以进一步优化,可以考虑用存储过程代替JDBC



6.数据库层,库存单行更新,增加多个槽位.

    单行更新场景


    增加槽位的表结构


    

    使用槽位分散行锁

    每种商品的库存,由4个槽位组成.

    事务开始,首先找到剩余数量最多的那个商品槽位.

    然后扣减该槽位的库存.

    这样一个行锁,可以变为4个行锁,系统吞吐量增加了4倍.

    (其实如果update的影响行数为0,表示该槽位已经没有库存.可以重复执行这个过程,再另选一个槽位)

  1. //开始事务
  2. select 商品,剩余数量,@槽位:=Slot from 库存表 
  3. where
  4. 商品='电视机' and 剩余数量>0 and
  5. 剩余数量=(select max(剩余数量) from 库存表 where 商品='电视机')
  6. limit 1;

  7. update 库存表 set 剩余数量=剩余数量-1 where 剩余数量>0 and 商品='电视机' and Slot=@槽位;

 //如果update的影响行数不为0,写订单明细表
commit;


7.数据库层,冷热商品分开.
    某些热点商品,可以单独放置在一个数据库处理
    比如苹果手机新品,特卖打折 10w部
    这种注定会热的商品,应该使用单独的数据库处理
    避免和普通商品竞争,堵塞本次活动其他商品的处理.

标签:剩余,Web,几个,数据库,想法,商品,秒杀,服务器
From: https://blog.51cto.com/u_13991401/5954013

相关文章

  • Spring中11个最常用的扩展点,你知道几个?
    前言在使用spring的过程中,我们有没有发现它的扩展能力很强呢?由于这个优势的存在,使得spring具有很强的包容性,所以很多第三方应用或者框架可以很容易的投入到spring的怀抱......
  • 分享几个网上比较好的开源项目
    这几天没事,在网上看了一下NET6的开源框架,有几个比较完整切好用的框架,分享一下   1、Admin.NET通用管理平台      这个框架用了几次,还不错,写法也感觉满......
  • redis 轻松实现分布式秒杀系统
    redis轻松实现分布式秒杀系统利用redis操作的原子性,轻松实现一个分布式的秒杀系统。假设设计背景:1万人去抢10个商品设计思路:在redis中存储一个list,每次用户请求抢购......
  • 这都一二三。。好几个月没更新咯
    哈哈哈,哈哈哈,很早之前想过会断更,没想到,没有一点的征兆,突然就,啪叽,好几个月没主要呢,前一段时间忙(好吧好吧,我忘了,哈哈哈),后来呢,抽空回家结了个婚(快撒欢),休了一个为期俩月的婚......
  • 推荐几个精致的web UI框架及常用前端UI框架
    以下是几个精致的webUI框架1.AliceuiAliceui是支付宝的样式解决方案,是一套精选的基于spm生态圈的样式模块集合,是Arale的子集,也是一套模块化的样式命名和组织规范,是......
  • 【文档】推荐几个文档编写神器
    一、参考资料​​docsify​​​​有了docsify神器,从此爱上看文档-简书​​​​登录·语雀​​......
  • 大道至简——工具类产品的几个思考方向
    因为之前没有接触过摹客的产品,对于一个经常使用Axure的产品经理,仅仅通过两周摹客的使用体验写出的体验文档确实不够严谨,所以以下除了表层的几点用户体验,重点还是谈一下对工......
  • 分享下昨天下午京东视频面试的面试题,看看你能回答几个
    我学生昨天下午参加的京东Java岗的视频面试,下面是面试过程中面试官提出的相关问题,这个是面试完成后自己在整理出来的面试题,基本上是差不多的,大家可以检测下自己能回答几个,同......
  • 功能测试的几个层次
    第一个层次,初级功能测试工程师,根据功能测试用例进行功能测试,这个可能是很多同学进入测试这一行最开始干的活,这个阶段会觉得测试工作很无聊,很没有技术含量,因为工作基本上......
  • 秒杀系统优化思路
    秒杀业务为什么难做im系统,例如qq或者微博,每个人都读自己的数据(好友列表、群列表、个人信息);微博系统,每个人读你关注的人的数据,一个人读多个人的数据;   秒杀系统,库存只......