关于库存扣减方案的思考总结

2024-01-11 10:18

本文主要是介绍关于库存扣减方案的思考总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文:修超

电商业务场景下,核心点主要围绕着用户(买家、卖家)、买家通过个性化的选择卖家商品,最终产生交易行为。整个电商业务流程是相当复杂的。不仅仅体现在业务上也体现在系统上,电商业务主要通过多个模块组成:比如会员、店铺、商品、交易、营销、支付、库存、物流、仓库、调度、风控等。通过各子模块领域的能力交互组合,串联出核心的交易流程。

在整个交易流程中,库存的处理是比较重要的,它包括商品的库存处理、营销权益的库存处理。从生命周期上来看有正向交易的库存扣减、逆向流程的库存回加。

在比如电商的营销场景,经常会遇到一些节日性的大促,比如双十一的红包雨的场景,该场景类似与秒杀,在整点即使上百万的用户同一时间涌入系统争抢红包。但红包本身是有限的,这就要求需要在极端的时间内对红包的数量做正确的扣减,比如每秒扣减200w次。但任何系统、机器都有其物理瓶颈存在。如何既能保证用户顺利领取到红包又不超发就成为一项非常困难的事情。

本文梳理介绍下常见库存的扣减方法

扣减的常用方案

常见的库存方案主要分为如下3种,可根据目前业务的发展情况,系统的能力诉求选择

  • 单库单记录

最常见的做法,主要存在是热点问题(大预算)、性能问题(数据库瓶颈),这种模式是得物之前的做法

  • 分库单记录

通过单库增加到多库,按照库存ID取hash均匀share的方式,提高性能,主要存在热点问题(大预算),目前得物的做法

  • 分布式多记录

库存提前分配到多个桶中,不同用户路由到不同的桶中,主要存在碎片问题、流量不均问题、动态扩容问题

不管哪种方案都是服务于业务的,选择合适的才是最好的。甚至于在个别业务场景下,库存的扣减是可以完全降级的

前面两种方案是相对比较简单的,下文主要介绍下分布式多记录情况下的扣减方案怎么做

分布式扣减方案

如果要支持上百万的TPS指标,整体的方案措施总结可以抽象做到如下三个点:

  1. 采用分片的方式(水平扩展方式解决单点),合理利用集群服务器及db的资源。在整体系统架构上解决单点性能瓶颈问题
  2. 分片后,针对单热点扣减采用一定的手段进行极致的优化(全缓存)
  1. 分片后,流量不均(预算动态分配),碎片(预算动态回收与重新分配)以及分片伸缩问题,通过master分配和slave分配的方式(主、子预算)进行解决

简单的分桶扣减

总结:存在流量不均、碎片、分片伸缩问题

桶集中管理扣减

通过增加扣减策略模块、库存调配模块(集中式管理)、请求调度策略(用户请求动态调度),三个模块的职责如下:

  • 库存策略模块:决定了库存应当如何被发放,将扣减链路中可敢于因素予以抽取,使得库存在扣减过程中能够被系统以及业务影响,从而扣减链路具备足够的扩展性,能够做到跟随业务动态变化
  • 库存调配模块:从新定义了库存分配策略,用于做个性化的按需分配,库存不在是一刀切分配在各个桶中,而是随着发放速率的变大而变大,桶流量越大给分配的库存也就越多。同时该模块实施监控整个发放链路,对库存不足以支撑发放的桶依据规则动态扩容、或者停止该桶的发放
  • 请求调度模块:能够动态调配扣减请求,以保证请求永远能够被路由到有库存的桶执行扣减

库存汇总:

目前得物这边采用的方式是分库和总库双向同步的模式汇总的。其实还有一种做法,可以通过增加“预算调度模块”,用户汇总各分库存的预算实时情况,然后借助缓存体系存入,用于使用场景的准实时读取。

总结

分布式基本是解决高并发库存扣减场景下唯一方案,不论是分桶还是将库存拉到本地执行扣减,都是这一思路。库存数据由集中式切换为分布式一定会带来更高复杂度的问题,而该问题是无法完全解决的,但我们可以采取各种方案尽力去降低该问题出现的概率,或者最大可能缓解该问题的影响面。

库存扣减涉及的技术点较多,包括远程的redis缓存、甚至本地缓存、锁机制、XTS事务,动态路由算法、最终一致性的消息通知等,还是很有技术挑战的。另外在库存扣减的策略上也很多技术的挑战点。比如基于db的扣减,调整为基于缓存的扣减,毕竟db的扣减受分表分库的最大数量限制,调整为通过缓存可以实现质的突破;另外在库存扣减提交上也可是做组提交的缓冲模式,缓冲模式一般在账务系统中是被广泛采用的方案,主要通过合并多次扣减请求,然后统一输入db的方式,这样可以有效降低热点减少锁并法。

此外库存扣减这块,限流、降级、容灾应急(借助分布式配置管理,比如nacos达到动态干预),监控、核对等稳定性运维相关的模块也是必不可少的。

这篇关于关于库存扣减方案的思考总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/594042

相关文章

Python中连接不同数据库的方法总结

《Python中连接不同数据库的方法总结》在数据驱动的现代应用开发中,Python凭借其丰富的库和强大的生态系统,成为连接各种数据库的理想编程语言,下面我们就来看看如何使用Python实现连接常用的几... 目录一、连接mysql数据库二、连接PostgreSQL数据库三、连接SQLite数据库四、连接Mo

Redis 多规则限流和防重复提交方案实现小结

《Redis多规则限流和防重复提交方案实现小结》本文主要介绍了Redis多规则限流和防重复提交方案实现小结,包括使用String结构和Zset结构来记录用户IP的访问次数,具有一定的参考价值,感兴趣... 目录一:使用 String 结构记录固定时间段内某用户 IP 访问某接口的次数二:使用 Zset 进行

解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)

《解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)》该文章介绍了使用Redis的阻塞队列和Stream流的消息队列来优化秒杀系统的方案,通过将秒杀流程拆分为两条流水线,使用Redi... 目录Redis秒杀优化方案(阻塞队列+Stream流的消息队列)什么是消息队列?消费者组的工作方式每

Git提交代码详细流程及问题总结

《Git提交代码详细流程及问题总结》:本文主要介绍Git的三大分区,分别是工作区、暂存区和版本库,并详细描述了提交、推送、拉取代码和合并分支的流程,文中通过代码介绍的非常详解,需要的朋友可以参考下... 目录1.git 三大分区2.Git提交、推送、拉取代码、合并分支详细流程3.问题总结4.git push

MySQL分表自动化创建的实现方案

《MySQL分表自动化创建的实现方案》在数据库应用场景中,随着数据量的不断增长,单表存储数据可能会面临性能瓶颈,例如查询、插入、更新等操作的效率会逐渐降低,分表是一种有效的优化策略,它将数据分散存储在... 目录一、项目目的二、实现过程(一)mysql 事件调度器结合存储过程方式1. 开启事件调度器2. 创

关于rpc长连接与短连接的思考记录

《关于rpc长连接与短连接的思考记录》文章总结了RPC项目中长连接和短连接的处理方式,包括RPC和HTTP的长连接与短连接的区别、TCP的保活机制、客户端与服务器的连接模式及其利弊分析,文章强调了在实... 目录rpc项目中的长连接与短连接的思考什么是rpc项目中的长连接和短连接与tcp和http的长连接短

Kubernetes常用命令大全近期总结

《Kubernetes常用命令大全近期总结》Kubernetes是用于大规模部署和管理这些容器的开源软件-在希腊语中,这个词还有“舵手”或“飞行员”的意思,使用Kubernetes(有时被称为“... 目录前言Kubernetes 的工作原理为什么要使用 Kubernetes?Kubernetes常用命令总

Python中实现进度条的多种方法总结

《Python中实现进度条的多种方法总结》在Python编程中,进度条是一个非常有用的功能,它能让用户直观地了解任务的进度,提升用户体验,本文将介绍几种在Python中实现进度条的常用方法,并通过代码... 目录一、简单的打印方式二、使用tqdm库三、使用alive-progress库四、使用progres

Android数据库Room的实际使用过程总结

《Android数据库Room的实际使用过程总结》这篇文章主要给大家介绍了关于Android数据库Room的实际使用过程,详细介绍了如何创建实体类、数据访问对象(DAO)和数据库抽象类,需要的朋友可以... 目录前言一、Room的基本使用1.项目配置2.创建实体类(Entity)3.创建数据访问对象(DAO

Java向kettle8.0传递参数的方式总结

《Java向kettle8.0传递参数的方式总结》介绍了如何在Kettle中传递参数到转换和作业中,包括设置全局properties、使用TransMeta和JobMeta的parameterValu... 目录1.传递参数到转换中2.传递参数到作业中总结1.传递参数到转换中1.1. 通过设置Trans的