秒杀系统 mysql_秒杀系统之数据库

秒杀系统的数据库中的库存加减操作是最为关键的点。12年天猫双十一的超卖事件,对平台的负面影响是非常巨大的。

数据库里做库存扣减,简单的可以用以下SQL来说明:

update stock_table set inventory=inventory-1 where item_id=xx and inventory>0

该SQL的含义是,对于指定商品在库存充足情况下扣减库存,该语句在MySQL数据库中执行可以保证其原子性(隔离级别大于等于Read-Committed)。

在秒杀业务场景下,对某个商品进行高并发扣减库存时,MySQL将会成为高并发业务的瓶颈:

高并发场景下的数据库瓶颈

MySQL使用WAL(write ahead log)方式来实现数据的持久化,即事务提交后,被更新数据写到硬盘后,才能返回成功。而硬盘的读写是整个服务中最耗时的操作,也是秒杀系统的瓶颈所在。

为了提高性能,针对数据库的优化就提到整个写库操作之前,即引入组提交机制,同时提交多个事务,这样多个写操作只会有一次写硬盘操作,对于该组事务,耗时仍然是一次硬盘,但提升了整个系统的吞吐量。

组提交机制并不是万能的,若事务之间存在冲突(比如针对同一商品进行库存修改),那么基于悲观锁进行并发控制的MySQL,只会排队执行,即后一个事务要等前一个事务提交完成后才能执行。使用扣减库存的SQL举例如下:

找到并对商品记录加锁 --> 判断库存余量 --> 修改库存余量 --> 写盘 --> 释放锁

针对同一个热点商品的多个并发事务,在上面加锁和释放锁之间的这段操作是无法做到并发执行的,此时系统的瓶颈就是磁盘IO。在大量并发事务都在争抢行锁的情况下,情况会进一步恶化,系统负载会突增,再加上锁冲突检测等额外代价,可能系统的整体吞吐会降低至个位数。

超卖风险

数据库一般会建立主备,在主库和从库间进行数据同步时会有一定的延迟,而一般系统中会采用从库读,主库写的方式。在高并发场景下,若主库数据未实时同步到从库,这样就会有超卖的风险。例如主库宕机后,部分binlog未及时同步到从库,此时从库切换为主库,恢复未同步成功的binlog,即已经扣减的库存,此时就会有超卖风险。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值