`
1028826685
  • 浏览: 936908 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类

实现秒杀的几个想法

 
阅读更多

转载:http://blog.itpub.net/29254281/viewspace-1800617/

还是秒杀.
秒杀一般有几个场景
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 剩余数量>and 
  5. 剩余数量=(select max(剩余数量) from 库存表 where 商品='电视机')
  6. limit 1;
  7. update 库存表 set 剩余数量=剩余数量-1 where 剩余数量>and 商品='电视机' and Slot=@槽位;
 //如果update的影响行数不为0,写订单明细表
commit
;


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

参考:
http://blog.itpub.net/29254281/viewspace-1783043/
    

http://jiagou.baijia.baidu.com/article/108134?qq-pf-to=pcqq.group

http://www.infoq.com/cn/presentations/seckill-solution-based-sql

分享到:
评论

相关推荐

    基于mq和redis实现的秒杀系统

    3. **分布式锁**:利用Redis的`SETNX`命令实现分布式锁,保证同一商品在同一时间只能被一个用户秒杀。 4. **限流控制**:通过设置Redis计数器,限制单位时间内处理的请求数量,防止流量过大。 5. **库存扣减**:使用...

    vue实现秒杀倒计时组件.docx

    该组件的实现思路主要包括以下几个步骤: 1. 猎取服务器当前时间:通过与服务器交互,获取当前服务器时间,以便统一时间标准。 2. 猎取用户当前电脑时间与服务器时间比对:通过比较用户当前电脑时间与服务器时间,...

    net实现秒杀活动

    Console程序常被用作后台任务或服务,例如在秒杀活动中,我们可以创建一个Console应用来执行定时任务,比如初始化秒杀商品的库存,或者在秒杀结束后清理相关数据。 Redis是一款高性能的键值存储系统,常用于缓存和...

    thinkphp实现商城秒杀、优惠券

    本教程将深入探讨如何利用ThinkPHP框架来实现一个具备秒杀和优惠券功能的商城系统。 一、ThinkPHP框架基础 ThinkPHP是一款流行的开源PHP框架,它提供了丰富的MVC(Model-View-Controller)结构支持,使得开发者可以...

    Java实现秒杀系统.zip

    在Java中实现秒杀系统涉及到多个技术点,包括高并发处理、数据库优化、分布式协调等。下面我们将详细探讨这些关键知识点。 1. **高并发处理**:秒杀场景下,系统需要承受短时间内大量用户的请求。Java中的多线程...

    springmvc+spring+mybatis+redis是实现秒杀

    下面将详细介绍这四个技术在实现秒杀中的作用和它们之间的协作。 1. SpringMVC: SpringMVC是Spring框架的一个模块,主要用于构建Web应用的Model-View-Controller(MVC)架构。在秒杀系统中,它负责接收用户的请求...

    php秒杀实现代码

    本篇文章将深入探讨如何使用PHP和Redis来实现一个高效的秒杀系统,这对于初学者来说是一个非常实用的学习案例。 首先,我们要了解秒杀系统的基本要求:高并发处理、数据一致性以及防止恶意刷单。Redis作为一个内存...

    Java实现电商秒杀项目

    当前用户秒杀商品时,首先去redis查询用户是否秒杀商品,没秒杀过,再去数据库查询,若该用户已秒杀过商品则不能,在参与秒杀同样商品。 若用户没有参与过秒杀商品,则去redis缓存预减库存,库存数量少于0,则返回...

    RabbitMQ实现抢购秒杀服务

    在构建高性能、高并发的在线服务时,抢购秒杀活动常常是考验系统承载能力的...在这个过程中,"seckill-order"可能是一个包含具体实现细节的文件,如订单创建的代码示例或配置文件,用于辅助理解和构建抢购秒杀服务。

    电商秒杀系统的设计与实现.pdf

    秒杀活动的一个显著特点是高并发访问,因为活动的吸引力导致短时间内大量用户涌入网站,这给电商系统的后台设计带来了极大的压力和挑战。 本篇文献详细介绍了基于Java语言开发的秒杀系统的设计与实现过程,该系统...

    秒杀系统java实现

    java实现秒杀系统@Controller @RequestMapping("seckill")//url:/模块/资源/{id}/细分 /seckill/list public class SeckillController { private final Logger logger = LoggerFactory.getLogger(this.getClass());...

    项目实现秒杀

    秒杀业务分析、架构规则、高并发带来的挑战、高并发下的数据安全以及秒杀的三种优化思路

    【JavaScript源代码】JavaScript实现限时秒杀功能.docx

    JavaScript 实现限时秒杀功能是在线购物平台常见的一种促销手段,通过倒计时的方式增加活动的紧迫感,激发消费者的购买欲望。以下是如何使用JavaScript来创建一个基本的限时秒杀倒计时功能的详解: 首先,我们需要...

    Java基础实现秒杀商品.rar

    在本项目"Java基础实现秒杀商品.rar"中,我们主要关注的是利用Java技术栈来构建一个基础的秒杀系统。这个系统包含了用户和管理员的交互功能,如登录、商品管理以及秒杀活动的设置。这是一次很好的实践,帮助初学者...

    秒杀代码实现.zip

    在这个“秒杀代码实现.zip”压缩包中,我们将会探讨如何使用Spring Boot框架结合Redis缓存来构建一个高效的秒杀系统,以解决商品超卖和用户重复购买的问题。 首先,我们要理解秒杀系统的关键挑战。一方面,由于瞬间...

    秒杀-秒杀系统-秒杀系统源码-秒杀管理系统-秒杀管理系统java代码-基于Web的秒杀系统设计与实现-秒杀系统设计与实现-代码

    秒杀-秒杀系统-秒杀系统源码-秒杀管理系统-秒杀管理系统java代码-秒杀系统设计与实现-基于springboot的秒杀系统-基于Web的秒杀系统设计与实现-秒杀网站-秒杀网站代码-秒杀平台-秒杀平台代码-秒杀项目-秒杀项目代码-...

    秒杀系统设计与实现.互联网工程师进阶与分析

    秒杀系统设计与实现是互联网行业中一个至关重要的领域,它涉及到高并发、高性能以及稳定性等核心挑战。在本文中,我们将深入探讨秒杀系统的设计原理、关键技术及其在实际项目中的应用,尤其关注Java语言下的解决方案...

    Javascript实现商品秒杀倒计时(时间与服务器时间同步)

    总结来看,通过AJAX请求获取服务器时间,计算网络传输耗时以及用户电脑与服务器的时间差,并在这些基础上调整页面倒计时时间,可以实现一个既准确又高效的秒杀倒计时功能。这种方法不仅保证了倒计时的同步性,还尽量...

Global site tag (gtag.js) - Google Analytics