0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

高并发场景下的库存管理,理论与实战能否兼得?

京东云 来源:jf_75140285 作者:jf_75140285 2024-08-07 15:27 次阅读

前言

本篇文章,是一篇实战后续篇,是基于之前我发了一篇关于如何构建高并发系统文章的延伸: 高并发系统的艺术:如何在流量洪峰中游刃有余

而这篇文章,从实践出发,解决一个真实场景下的高并发问题:秒杀场景下的系统库存扣减问题。

随着互联网业务的不断发展,选择在网上购物的人群不断增加,这种情况下,会衍生出一些促销活动,类似抢购场景或者热销热卖场景,在高峰时段的下单数量会非常大,也意味着对数据库中畅销商品的库存操作十分频繁,需要频繁查库存和更新库存。这属于高读写场景,比起单独的并发读和并发写来说,业务场景更复杂一些。那么这种高并发为了保证库存数据一致性,一般会在数据库更新时进行加锁操作,以保证系统不会发生超卖情况。

我们应该如何应对呢?大家可以根据我之前那篇文章中的思维导图,跟随我的思路,一起来看如何解决当前场景下的高并发问题。



小试牛刀

面对库存扣减的场景,我们第一个考虑到是数据一致性问题,因为超卖会对我们的履约和客户信誉造成影响。所以一般情况下,在数据库更新时进行加锁操作,以保证系统不会发生超卖情况。所以更多方案是提高数据库性能方法,比如增加硬件性能,优化乐观锁,提升锁效率,优化SQL性能等。对于一些大型系统,也衍生出一些基于分片的库存方案,通过分库分表增加并发吞吐量。

当然那这样不够,因为MySQL数据库的读写的并发上线能力是有限的,我们还是需要再进一步优化我们的方案。这里就要参考之前我写的那篇文章中的思维导论了,这里常见解决方案就是,引入缓存机制。

如下图所示,我们把读请求进行缓存,每次库存校验时,我们引入redis缓存,读请求通过缓存,增加接口性能,然后库存扣减时,在进行缓存同步。



wKgZomazGDqAXmZqAADJ1uhNpPM236.png

但这种方式存在很大问题: 所有请求都会在这里等待锁,获取锁有去扣减库存。在并发量不高的情况下可以使用,但是一旦并发量大了就会有大量请求阻塞在这里,导致请求超时,进而整个系统雪崩;而且会频繁的去访问数据库,大量占用数据库资源,所以在并发高的情况下这种方式不适用。同时这个方案还会存在mysq和redis的数据同步不一致的情况,导致高并发情况下,出现超卖。

所以这种方案虽然简单,但是无法满足高并发场景,我们必须得pass。

循序渐进

为此,我们可以进行一次优化,通过架构维度进行调整。

在这个方案中,我们将库存操作封装成一个单独模块,这个方案的优化点在于,所有库存的查询和扣减都围绕redis进行。当发生库存扣减操作时,会直接更新redis,同时采用异步流程,更新MySQL数据库。这样以来,我们的性能会比直接访问MySQL数据库高效不少,并发能力会有不少提升。

流程如下:



wKgaomazGDyASV7tAAEkk0nsHK4146.png



但这个方案依然有缺陷,它的点在于redis的单点性能问题。该方案的最大并发性能取决于redis的单点处理能力。而如果想要进一步提升并发能力,该方案不具备水平扩展能力。那么,这个方案,依然不是我们最优的选择。

大显身手

那么接下来,我们需要考虑的是如何可以实现我们业务系统并发能力的水平扩展能力。当然这里也不是凭空来想,我们可以思考一下,业内成熟的一些中间件是如何实现高并发的,这里我们可以两个我们常见的框架:kafka和elasticsearch。

上述我们常见的两个中间件框架,都以可以水平能力扩展著称。那么仔细思考一下他们的技术架构不难发现,他们的核心其实都是采用了一种所谓的分片实现的。那么问题来了,我们的库存扣减,能不能实现分片呢?或者换一个思路思考这个问题:我们的库存逻辑是否可以转化为分布式库存进行存储和扩展呢?

有了以上的思路,我们就可以开始构建我们的架构方案了。接下来,我先把架构图贴出来:

wKgZomazGD2AKyrRAAJxZd9x5As304.png

在这个架构方案中,是以Redis缓存为实现基础,结合Mysql数据存储,通过一套控制机制,保证库存的分布式管理。在该方案中,有一些特定的业务模块单元需要说明。

1. partition

熟悉kafka的人对partition一定不陌生。在本架构方案之中,该业务架构中的partition的概念是一组基于redis来实现的库存分片,分别存储一部分库存大小。

在一个partition中,会存有一定量的预占库存量,当有请求服务进行库存扣减时,只需要选择其中一个partition即可,这样以来,就可以减轻单节点的压力,同时可以基于redis集群的可扩展性,实现partition的水平扩展。

分布式系统常见的一个问题就是数据倾斜问题,因为严重的数据倾斜,会让我们分布式方案瞬间瓦解,导致单点承担高并发。那么该方案下的数据倾斜问题如何解决呢?

最终,我想到的解决方案类似养宠物狗时买的那种定时投喂仪器,每天通过定时定量投喂,来保证宠物狗不会被饿到或者吃撑。

如果最初把所有库存全部平均到每个partition中,当有多个大库存扣减打到一个partition上时,会造成该partition上出现库存被消耗光,而失去后续提供库存扣减能力。为了解决这个问题,我在partition中采取的是动态库存注入和子域隔离的方案。具体方案如下图:

wKgaomazGD-AfR_CAAD2n5rEYAc592.png

每个partition会有两个子域,调度器中会记录每个partition当前激活的子域,每次库存扣减,会扣减激活的子域中的库存值。而当激活的子域库存值低于设定阈值是,会切换子域,冷却当前子域,激活另一个子域。被冷却的子域会触发任务触发器,实现预占库存的数据同步。

子域中会存储一定额度的库存值,不会存储很大的量,这样就可以保证动态的预占库存实现,从而解决库存倾斜的问题。

当然为了更好的管理partition,我们需要单独开发一个partition调度器模块,来负责管理管理众多partition资源,那么这个调度器的具体功能包括:

1.调度器中有一个注册表,会记录 Partition的key值,外部服务获取partition key是需要通过调度器获取,调度器会记录每个partition的库存余量和partition和子域信息

2.当partition无法再获取预占库存,且库存耗尽时,调度器会从注册表中摘除该partition信息。

3. 调度器可以采用随机或者轮训的方式获取partition,同时每次也会校验partition剩余库存是否满足业务扣减数量,如果剩余库存小于业务扣减数量,将会跳过该partition节点。

2. 异步更新库存

第二个核心模块就是更新库存管理了,这块你可以理解为异步流程机制,通过异步化操作,来减轻系统的高并发对数据库的冲击。

更新库存会有一个明细表,记录每个partition库存扣减信息,明细表会有一个同步状态,有两种情况可以出发库存同步MQ消息:

第一. 当每个partition中的明细数据条数超过设定阈值,会自动触发一次MQ消息。

第二. 每间隔额定设定时间(默认设置1秒), 会触发一次当前时间段内每个partition产生的库存扣减明细信息,然后发送一次MQ消息。

两中触发方案相互独立,互不影响,通过同步状态和明细ID实现幂等。

3. 预占库存管理和库存管理

接下来就是关于库存的底层数据结构设计了。这里会引入一个在电商行业很共识的概念:预占库存。

在库存领域层中,库存分为预占库存和库存两个模块,这里面的库存关系实例如下:

假设当前商品的库存值为10000件,当前partition触发一次预占库存任务,领取400件, 然后假设此时收到MQ库存消费更新消息,更新30件。随后partition又触发一次预占库存任务,零陵区了100件。库存变化如下图所示:

wKgZomazGEGAKia2AAEK_vjh7Qg813.png

其中 实际库存= 预设库存池 + 预占库存。

每次预占库存任务触发,会从预设库存池中扣减,如果预占库存池清空,则partition就无法在获取预占库存,调度器会将它从注册表中摘除。

而每次MQ更新库存消息,会更新实际库存量,同时对预占库存和扣减库存值进行修改,这个操作具有事务性。

总结

通过这次的案例分析,我们其实是通过方法论结合实际业务场景的方式出发,设计了我们的系统架构。剥离业务场景,其实本质就是通过缓存和异步流程来实现系统的高并发,同时让系统具备拥有水平扩展的能力。但这个方法论在与实际业务结合时,还是会有很多很多需要思考和细化的点,比如分布式思想的使用,比如预占库存的逻辑设计等等。

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 库存管理
    +关注

    关注

    0

    文章

    11

    浏览量

    6731
  • Partition
    +关注

    关注

    0

    文章

    3

    浏览量

    7761
  • 调度器
    +关注

    关注

    0

    文章

    98

    浏览量

    5200
收藏 人收藏

    评论

    相关推荐

    如何去实现一种基于SpringMVC的电商并发秒杀系统设计

    参考博客Java并发秒杀系统API目录业务场景要解决的问题Redis的使用业务场景首页倒计时秒杀活动,抢购商品要解决的问题
    发表于 01-03 07:50

    ATC'22顶会论文RunD:高密并发的轻量级 Serverless 安全容器运行时 | 龙蜥技术

    和 FireCracker 都提供了实现这种安全容器的实践经验。(图1/目前主流的安全容器模型,以及对应的软件栈架构)在 Serverless 场景,函数的轻量级和短期运行的特性使得高密度容器部署和
    发表于 09-05 15:18

    模糊控制理论库存货位管理中的应用

             针对库存货位布局线性规划的难建模和全重排问题,提出了基于模糊控制理论库存货位布局方法。在以某公司仓库的实际数据平台基础
    发表于 09-14 07:56 12次下载

    负荷管理系统中的并发通信设计与实现

    负荷管理系统中的并发通信设计与实现摘 要 大规模并发通信的管理与控制是计算机监控领域研究的热点与难点之一。本文以厦门电业局负荷管理系统为例,
    发表于 11-01 09:50 13次下载

    核方法在库存管理系统中的应用

    针对库存管理的特点,介绍了目前常用的数据挖掘技术在库存管理系统中的应用。同时,对于目前库存管理
    发表于 01-07 15:59 6次下载

    Java并发编程实战

    Java并发编程实战
    发表于 03-19 11:24 7次下载

    物联网是如何驱动库存管理

     基于物联网的库存管理解决方案通过提供物品状态、位置和移动的实时更新,为制造商提供了原材料和组件,在制品和成品生产流程中的精确可见性,以便库存管理人员查看单个
    发表于 03-13 10:36 558次阅读

    并发性能调优是在技术进阶赛道变得厉害的加分项

    、优化方案、架构演进,你将同时收获高薪、话语权、成就感和不可替代性。从各大厂的岗位需求可以看出:并发实战是大厂P6+岗位必备能力,比普通岗薪资 200%。从 P6+ 到 P8 ,如
    的头像 发表于 09-18 10:39 1312次阅读

    ERP库存管理系统是什么,具有哪些特点及优势

    ERP库存管理系统是库存管理系统中一种新型的管理系统,与以往的库存
    的头像 发表于 11-26 15:12 6990次阅读

    解密并发业务场景典型的秒杀系统的架构

    中,就更别提如何构建并发系统了! 究竟什么样的系统算是并发系统?今天,我们就一起解密并发
    的头像 发表于 11-17 10:32 2147次阅读
    解密<b class='flag-5'>高</b><b class='flag-5'>并发</b>业务<b class='flag-5'>场景</b><b class='flag-5'>下</b>典型的秒杀系统的架构

    【源码版】基于SpringMVC的电商并发秒杀系统设计思路

    参考博客Java并发秒杀系统API目录业务场景要解决的问题Redis的使用业务场景首页倒计时秒杀活动,抢购商品要解决的问题
    发表于 01-12 10:23 0次下载
    【源码版】基于SpringMVC的电商<b class='flag-5'>高</b><b class='flag-5'>并发</b>秒杀系统设计思路

    通过秒杀商品来模拟并发场景

    并发场景在现场的日常工作中很常见,特别是在互联网公司中,这篇文章就来通过秒杀商品来模拟并发场景
    的头像 发表于 02-07 10:47 377次阅读

    工业物联网平台如何应对并发应用场景

    面对的巨大挑战。对此,数之能提供并发、官翻机接入的工业物联网平台,可以适应并发场景应用需求。
    的头像 发表于 09-06 14:21 488次阅读

    并发内存池项目实现

    本项目实现了一个并发内存池,参考了Google的开源项目tcmalloc实现的简易版;其功能就是实现高效的多线程内存管理。由功能可知,并发
    的头像 发表于 11-09 11:16 549次阅读
    <b class='flag-5'>高</b><b class='flag-5'>并发</b>内存池项目实现

    什么场景需要jvm调优

    JVM调优是指对Java虚拟机进行性能优化和资源管理,以提高应用程序的运行效率和吞吐量。JVM调优的场景有很多,下面将详细介绍各种不同的场景
    的头像 发表于 12-05 11:14 984次阅读