解决并发锁的问题,有两种办法:
- 应用层排队 。通过缓存加入集群分布式锁,从而控制集群对数据库同一行记录进行操作的并发度,同时也能控制单个商品占用数据库连接的数量,防止热点商品占用过多的数据库连接 。
- 数据层排队 。应用层排队是有损性能的,数据层排队是最为理想的 。业界中,阿里的数据库团队开发了针对 InnoDB 层上的补丁程序(patch),可以基于 DB 层对单行记录做并发排队,从而实现秒杀场景下的定制优化 。注意,排队和锁竞争是有区别的,如果熟悉 MySQL 的话,就会知道 InnoDB 内部的死锁检测,以及 MySQL Server 和 InnoDB 的切换都是比较消耗性能的 。另外阿里的数据库团队还做了很多其他方面的优化,如 COMMIT_ON_SUCCESS 和 ROLLBACK_ON_FAIL 的补丁程序,通过在 SQL 里加入提示(hint),实现事务不需要等待实时提交,而是在数据执行完最后一条 SQL 后,直接根据 TARGET_AFFECT_ROW 的结果进行提交或回滚,减少网络等待的时间(毫秒级) 。目前阿里已将包含这些补丁程序的 MySQL 开源:AliSQL
小结:高读和高写的两种处理方式大相径庭 。读请求的优化空间要大一些,而写请求的瓶颈一般都在存储层,优化思路的本质还是基于 CAP 理论做平衡 。
总结一下当然,减库存还有很多细节问题,例如预扣的库存超时后如何进行回补,再比如第三方支付如何保证减库存和付款时的状态一致性,这些也是很大的挑战 。
高可用
盯过秒杀流量监控的话,会发现它不是一条蜿蜒而起的曲线,而是一条挺拔的直线,这是因为秒杀请求高度集中于某一特定的时间点 。
这样一来就会造成一个特别高的零点峰值,而对资源的消耗也几乎是瞬时的 。所以秒杀系统的可用性保护是不可或缺的 。
流量削峰
对于秒杀的目标场景,最终能够抢到商品的人数是固定的,无论 100 人和 10000 人参加结果都是一样的,即有效请求额度是有限的 。并发度越高,无效请求也就越多 。
但秒杀作为一种商业营销手段,活动开始之前是希望有更多的人来刷页面,只是真正开始后,秒杀请求不是越多越好 。
因此系统可以设计一些规则,人为的延缓秒杀请求,甚至可以过滤掉一些无效请求 。
①答题
早期秒杀只是简单的点击秒杀按钮,后来才增加了答题 。为什么要增加答题呢?
主要是通过提升购买的复杂度,达到两个目的:
- 防止作弊 。早期秒杀器比较猖獗,存在恶意买家或竞争对手使用秒杀器扫货的情况,商家没有达到营销的目的,所以增加答题来进行限制 。
- 延缓请求 。零点流量的起效时间是毫秒级的,答题可以人为拉长峰值下单的时长,由之前的 <1s 延长到 <10s 。这个时间对于服务端非常重要,会大大减轻高峰期并发压力;另外,由于请求具有先后顺序,答题后置的请求到来时可能已经没有库存了,因此根本无法下单,此阶段落到数据层真正的写也就非常有限了 。
答题目前已经使用的非常普遍了,本质是通过在入口层削减流量,从而让系统更好地支撑瞬时峰值 。
②排队
最为常见的削峰方案是使用消息队列,通过把同步的直接调用转换成异步的间接推送缓冲瞬时流量 。
除了消息队列,类似的排队方案还有很多,例如:
- 线程池加锁等待
- 本地内存蓄洪等待
- 本地文件序列化写,再顺序读
- 请求积压 。流量高峰如果长时间持续,达到了队列的水位上限,队列同样会被压垮,这样虽然保护了下游系统,但是和请求直接丢弃也没多大区别 。
- 用户体验 。异步推送的实时性和有序性自然是比不上同步调用的,由此可能出现请求先发后至的情况,影响部分敏感用户的购物体验 。
③过滤
过滤的核心结构在于分层,通过在不同层次过滤掉无效请求,达到数据读写的精准触发 。
常见的过滤主要有以下几层:
- 读限流:对读请求做限流保护,将超出系统承载能力的请求过滤掉 。
推荐阅读
- 简单几步学会做网站,却不懂如何赚钱?这里分享给你8种变现方法
- 只需三种手段,将传统的网站的性能提高 24%
- 网站被降权了应该怎么办?
- 教你使用nginx部署网站教程
- 怎么勾引百度蜘蛛访问你的网站
- 什么是网站TDK标签
- 110个人信息查询网 110网站查询住宿记录
- 网站漏洞测试与修复漏洞Laravel框架
- 老板说网站慢,我们总结了三大阶段提升性能
- 武夷学院大型幼儿茶艺表演感动外国友人
