# 《Seckill秒杀系统》第59章:商品库存分库分表与分桶设计

作者:冰河
星球:http://m6z.cn/6aeFbs (opens new window)
博客:https://binghe.gitcode.host (opens new window)
文章汇总:https://binghe.gitcode.host/md/all/all.html (opens new window)
源码获取地址:https://t.zsxq.com/0dhvFs5oR (opens new window)

沉淀,成长,突破,帮助他人,成就自我。

  • 本章难度:★★★☆☆
  • 本章重点:重点理解并掌握商品库存分库分表与分桶的设计思想,掌握商品库存分库分表与分桶的核心,并能够将分库分表与分桶设计的核心思想灵活运用到自身实际项目中。

大家好,我是冰河~~

在前面的章节中,我们完成了秒杀系统的微服务改造,将秒杀系统由单体应用架构升级成微服务架构,分别通过TCC模型、AT模型和可靠消息最终一致性模型解决了分布式事务问题,并且对秒杀系统的下单流程、扣减商品库存的流程进行了异步化设计和实现。秒杀系统应用层面的性能得到了极大的提升。

# 一、前言

通过对秒杀系统的微服务化改造,对下单流程和扣减商品库存的流程进行异步化设计和实现后,我们的秒杀系统从应用层面上,性能得到了极大的提升。但是当秒杀达到数十万级甚至更高规模的并发时,即使已经对系统进行了优化,进行了异步化设计,也很难轻松与体面的应对这么大的并发场景。目前,我们的秒杀系统的性能瓶颈已经出现在数据库层面,所以,我们需要对秒杀系统中数据库的读写操作进行优化。

# 二、本章诉求

在我们开发的秒杀系统中,对数据库的读写操作进行优化,并不是简单的进行主从复制和分库分表。而是需要从秒杀特有的瞬时高并发、大流量的业务场景出发,针对场景进行数据库优化。

对于秒杀这种场景来说,关键是要支撑瞬时的高并发、大流量,大量用户抢购商品下单时,会频繁调用查询和更新商品库存的接口,所以,对于商品库存来说,我们需要增强数据库的读写性能。在具体设计上,就是要对商品的库存进行分库分表和分桶设计,使得商品的库存不再由单数据库进行存储,扩展成多台数据库,并且在每个数据库中,又对商品的库存进行分桶设计。同时,在缓存层面,也需要对商品的库存进行分桶设计。

# 三、库存优化目标

在正式对商品库存进行分库分表和分桶设计之前,我们先来确定下库存优化的目标,也就是分库分表和分桶设计的目标,这样在后续的实现中更有针对性。这里,我主要把库存优化的目标分成了六点:分库设计、分表设计、分桶设计、缓存设计、一致性设计和兼容性设计,如图59-1所示。


  • 根据秒杀商品对库存进行分库设计:使得相同秒杀商品的库存能够路由到同一数据库进行处理。
  • 根据秒杀商品对库存进行分表设计:使得相同秒杀商品的库存能够路由到同一数据库中,然后再进一步根据商品id进行分表。
  • 根据秒杀商品对库存进行分桶设计:对于秒杀系统来说,分库分表主要提升的是多场秒杀活动的并发处理能力,而分桶设计主要解决的是单场秒杀活动的并发处理能力。
  • 根据库存的分库分表和分桶方案,设计对应的库存缓存方案:根据库存的分库分表和分桶方案,为商品的分桶库存设计分桶缓存方案:真正扣减商品分桶库存之前会预扣缓存中的分桶库存数据,以提高系统的并发处理能力。
  • 数据一致性设计:在缓存与数据库的数据一致性层面,基于分库分表和分桶设计,在缓存层面实现弱一致性,数据库层面实现强一致性。
  • 兼容性设计:对于新增的商品库存分库分表和分桶设计,要兼容之前的商品库存设计,能够根据简单的配置进行自由切换。

# 四、分库分表设计

在分库分表的设计上,这里我们使用了三个库实现(实际场景可以根据具体需要灵活配置分库和分表的数量),默认一个商品库和两个库存库,将商品的库存信息从商品表中独立出来,单独进行分库分表和分桶设计。

  • 商品库:在秒杀下单的过程中,主要以读操作为主,比如获取秒杀商品详情信息等。
  • 库存库:在秒杀下单的过程中,主要以写操作为主,主要是在下单过程中扣减商品的库存,分摊数据库的写压力。

# 查看完整文章

加入冰河技术 (opens new window)知识星球,解锁完整技术文章与完整代码