有了前面几章数据库部分的铺垫,相信读者现在都认识到了,在库存需要一单一单地减掉的情况下,这个减库存的过程在宏观上必然有一个单点——这个单点需要把所有的需求排成队,一个一个地执行完成。
在一个没有经过任何复杂架构设计的电商系统中,扣库存需要基于 MySQL 中update
语句自带的事务性来实现的排队:每一句update
在执行的时候,MySQL 都会给它自动包裹成一个事务来执行。MySQL 的事务确实非常的严谨,执行不会出错,但是性能实在是不行,而且如果瞬间并发大量有冲突的事务,还会引发死锁,导致连接数暴涨,数据库服务挂掉。
怎么解决这个问题呢?很简单,用单独设计的队列把这个“单点”的工作接管过来,让 MySQL 能够舒服又高效地运行。
在团购秒杀活动刚开始的几分钟,下单压力确实很大,但是几分钟后压力就降到了比日常平峰期高不了多少的水平。所以,我们可以用队列来把短期内暴增的数据库压力稍微地均匀分摊一下,让库存的扣减和订单的生成稍微等待一下,我们的数据库就不会挂,秒杀活动就能够正常地进行下去。
超售问题的本质是计算机经典的“多线程”问题——在宏观上,同一个时刻有两个线程需要对同一个变量分别执行“减去 1”这个运算,如果我们不对这种并发行为做处理,最终可能两个线程都执行成功了,但是这个变量一共也只被减去了 1,而不是预期的 2。
这个问题用队列也能解决,而且有两种解决方案:
📙 高并发的哲学原理 《Philosophical Principles of High Concurrency》
Copyright © 2023 吕文翰