实现秒杀的几个想法(续)
转自: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服务器监听到限额的变化,就会重新初始化各自的商品剩余数量.
模拟示例:
- private static ConcurrentHashMap<String,Integer> map=new ConcurrentHashMap<String, Integer>();
- private void zooKeeperHandle(){
- //将ZooKeeper的变化,初始化到Web服务器全局容器
- map.put("电视机", 125);
- map.put("手机", 125);
- map.put("衣服", 125);
- }
假设用户请求秒杀电视机,它只是锁了该Web服务器电视机的数量。(该Web服务器手机和衣服还可以继续并发处理,当然其他的Web服务器也在同时处理电视机的秒杀请求)
这样缩小了锁定的范围,增加了系统处理的吞吐量.
如果这个剩余数量大于零,则将用户ID放入电视机购买队列,然后告知用户秒杀成功
如果这个剩余数量等于零,则告知用户秒杀失败.即便别的Web服务器还有电视机的剩余配额.
3.ZooKeeper层,ZooKeeper变更库存信息
假设活动期间,需要修改库存信息。
两种可能,
第一种,该商品已经卖了500件,电商不想继续卖了.
第二种,从仓库中又找到了一些积压库存..
两种情况,都直接修改ZooKeeper中相应商品的配额.
Web服务器会监听变化,并重新初始化全局容器.
4.消息队列层,多消费者处理
消费者主要是从队列获取购买请求,发送至数据库
扣减数据库库存
写订单明细记录
5.数据库层,使用存储过程代替JDBC调用
由于使用了多消费者处理同一队列,增加吞吐量,避免队列堆积过大.
但是多消费者,必然导致数据库出现单行更新问题.
单行更新问题就是多个线程,并发修改同一条记录,导致事务相互阻塞.浪费了数据库宝贵的处理能力.
考查下图.
假设消费者到数据库的网络是1毫秒
那么相对于存储过程,使用JDBC的方式,每个事务将至少多持有行锁2毫秒.
所以进一步优化,可以考虑用存储过程代替JDBC
6.数据库层,库存单行更新,增加多个槽位.
单行更新场景
增加槽位的表结构
使用槽位分散行锁
每种商品的库存,由4个槽位组成.
事务开始,首先找到剩余数量最多的那个商品槽位.
然后扣减该槽位的库存.
这样一个行锁,可以变为4个行锁,系统吞吐量增加了4倍.
(其实如果update的影响行数为0,表示该槽位已经没有库存.可以重复执行这个过程,再另选一个槽位)
- //开始事务
- select 商品,剩余数量,@槽位:=Slot from 库存表
- where
- 商品='电视机' and 剩余数量>0 and
- 剩余数量=(select max(剩余数量) from 库存表 where 商品='电视机')
- limit 1;
- update 库存表 set 剩余数量=剩余数量-1 where 剩余数量>0 and 商品='电视机' and Slot=@槽位;
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
转载于:https://www.cnblogs.com/yanwei-wang/p/5957137.html
实现秒杀的几个想法(续)相关推荐
- 脑科学布局-陈天桥(转)
作者:闲吟客 来源:知乎 从下面的资料看陈天桥布局脑科学已经很长时间了,而且盛大也在做相关布局.另外据说他曾经和国内学校商量捐款,让对方给他一个报告,对方一直拖着显得很不在乎,让陈觉得他们钱多不需要捐 ...
- 一个想法(续三):一份IT技术联盟创业计划书,开启众筹创业征程
写在创业计划书之前的话: 昨天在闪存里我@了dudu,说:我要借钱,不久dudu回了我:傍个富婆. 当然,dudu以为我是玩笑,其实,我的确是开玩笑的,哈. 不过我正在执行一个创业计划,如果启动,我会 ...
- JSD-2204-(业务逻辑开发)-续秒杀业务-消息队列-Day14
1.续秒杀业务准备 1.1设置定时任务 1.1.1将库存和随机码保存到Redis 利用Quartz将库存和随机码保存到Redis 1.创建Job接口实现类 2.创建配置类,配置JobDetail和Tr ...
- 一个想法(续五):IT联盟创业计划:现阶段进度公示、疑问解答及进行中的计划...
前言: 首先今天是元宵节,先祝大伙元宵节快,单纯的快乐! 然后看看开展中的计划: IT联盟创业计划众筹发起:一个想法(续三):一份IT技术联盟创业计划书,开启众筹创业征程 IT联盟创业计划众筹进度:一 ...
- 秒杀多线程第十篇 生产者消费者问题 (续)
使用java 和semaphore实现的 ,多个生产者和多个消费者的问题. 1.使用Semaphore,Semaphore的大小设定为BUFFER_LENGTH.也就是同时最多有这么多线程来操作缓冲区 ...
- 一个想法(续四):IT技术联盟创业众筹进度公示
为了将整个创业过程更加的公开公正透明化,特开此篇用于展示众筹进度. 首轮众筹进度如下:(本活动截止于2017-3-6) 本文原创发表于博客园,作者为路过秋天,原文链接:http://www.cnblo ...
- python 抓包秒杀_Python 爬虫,推荐一款简单的抓包工具(续)
2. Jmeter 配置 2-1创建线程组 打开 Jmeter 软件之后,保存为一个 jmx 文件 选中默认的测试计划,右键,添加一个一个线程(用户),选择线程组,这样会创建一个线程组 2-2为线程组 ...
- Redis03-优惠券秒杀
一.分布式Id:订单id 在分布式架构下,传统生成Id的方式已经不再适用,应该生成全局唯一的 分布式Id需要满足的五个特性:全局性.唯一性.安全性.可用性.高性能 @Component public ...
- 借助Redis锁,完美解决高并发秒杀问题
欢迎关注方志朋的博客,回复"666"获面试宝典 场景:一家网上商城做商品限量秒杀. 1 单机环境下的锁 将商品的数量存到Redis中.每个用户抢购前都需要到Redis中查询商品数量 ...
最新文章
- 隐马尔科夫模型原理解析
- activiti 设置可选处理人_新品速递|高端系列!慧明DF系列线性相位处理专业音箱处理器...
- 如何优雅的处理Restful
- java 数据源调用_实战分享: Spring boot 调用之间实现动态数据源
- 【Hbase】HBase 更改表名
- 服务器磁盘读取暴涨_8分钟了解服务器硬件知识
- AutoCAD 2022 for Mac v2022.2.1中文版
- Junit框架使用--JUnit常用断言及注解
- Tomcat8的下载、安装、配置
- 服务器pbs傻瓜操作
- IP Forwarding打开
- 北大教授:学术会议,已沦为表演
- 三伏天不能吃冷饮?7月这些蜚语你中招没
- python实现 pdf转png格式
- 成功解决 KeyError: Unable to open object (object x doesnt exist)和no file found ./SGN/asd.phl
- 中文转UTF-8 和UTF-8转中文
- 巴西龟购买指南(避免掉坑)
- java局域网通信_java局域网通信
- Grad-CAM: Visual Explanations from Deep Networks via Gradient-based Localizati论文精读及资源整理
- (1146, Table 'django.django_session' doesn't exist)