千万级电商流量下如何防止库存超卖?

架构小魔方 2024-09-10 20:15:13

在电商领域,库存是非常核心的一块,决定了用户下完单之后,是否能够按时履约,如果因为库存不足,导致了超卖现象,将直接导致用户的投诉以及平台失约后带来的负面影响。

产品层面

从产品层面,根据各家的业务商品特点,常见的电商锁库存主要有以下几种做法

1、加入购物车即锁库存:这种一般是针对于较为稀缺的货品,可以采用这种方式,通过用户加购,提前锁定库存,以便于用户有足够的时间去完成下单,支付。此典型的代表就是唯品会,但这种方式也存在着一些缺点,因为从加购到用户下单以及支付,整个过程中,用户的购买的决策链条还是比较长的,这样会导致如果用户迟迟没有做出购买决策,会带来其他用户无法购买的现象。

2、下单即锁库存,即下单完成就锁定库存:采用先到先得的方式,大多数的电商目前都采用这种方式,缺点和第一种情况类似,会存在着用户下单后,迟迟不付款,而导致其他人无法购买的情况出现

3、付款即锁库存,即完成了支付后才锁定库存:这种方式能最大程度满足用户谁先付款就是谁的,属于实实在在的交易,但这种从技术角度很难实现,很容易出现超卖后导致的爽约现象出现,一般电商采用这种方式也比较少,无法用于商品库存数量少这种场景,一般都是货源较为充足,就算缺货也能及时进行货源补充的这种场景。

技术层面

从技术层面,要实现在高并发流量下如何防止库存超卖现象?

一、利用数据库的事务一致性以及锁机制:在实现处理库存扣减时,常见的方法是通过数据库操作实现。确保操作的原子性和有序性通常可以通过加锁实现,一般是采用悲观锁或者是乐观锁来达到这个目的.

-- 开始事务BEGIN;-- 查询商品信息并加锁SELECT qty FROM Product WHERE id = 1 FOR UPDATE;-- 扣减商品库存2UPDATE Product SET qty = qty-2 WHERE id = 1 and qty-2>=0;-- 提交事务COMMIT;

或者是

-- 开始事务BEGIN;UPDATE Product SET qty = qty-2 , version=version+1 WHERE id = 1 and version=${version} and qty-2>=0-- 提交事务COMMIT;

但这种方案,很难在并发较高的场景下使用,一般MySQL的热点行更新最多也就承受200左右的并发更新。

二、基于Redis Lua 脚本实现:这种是在并发较高的系统中采用了,它充分利用Redis Lua 脚本的原子性这一特点去实现。

local product = KEYS[1] -- 商品的键名-- 获取商品当前的库存量local remaining_qty = tonumber(redis.call("GET", product))local reduce_qty= tonumber(ARGV[1]) -- 扣减的数量-- 如果库存足够,则减少库存并返回新的库存量if remaining_qty >= reduce_qty then redis.call("DECRBY", product, reduce_qty) return trueelse return falseend

但该方案也存在着一定的问题:

1、采用的是基于Redis缓存的存储方式,存在着一定程度的丢数据的可能性,存储的可靠性没有基于MYSQL的存储可靠,当然现在很多云Redis服务,在可用性也做了非常多的高可用机制,在满足性能的同时尽可能的避免Redis数据丢失。

2、Redis的Lua脚本不能跨分区使用,如果使用了Redis的集群版,在应对下单多个商品的时候,只能一个一个的扣减,那其中一个失败,需要对其他商品进行回滚,那整个过程就可能存在着没有回滚成功的情况,将会造成商品的少卖,当然少卖比超卖在业务处理方面会更简单,一般是通过库存核对,确定少卖后再将库存回滚上架后供消费者购买。

三、两者方案进行结合,在面向C端用户购买的场景,采用Redis的Lua脚本进行扣减,通过MQ异步的方式进行数据同步(也有一些是基于Redis的AOF日志重放进行同步,一般云厂商的Redis不支持这种做法),同步后,由数据库记录库存流水数据,在通过库存流水进行数据库层面的库存异步扣减动作,这种方案可能是目前采用最多的方案,即避免了高并发场景下,数据库的并发能力不足的问题,也在一定程度解决了担心数据丢失的风险。

四、基于缓存分桶扣减方案,通俗来讲就是将缓存集群的一个key就对应于于一个"分桶"。基于分桶策略去实现了一个高并发场景下库存扣减动作,这种方案较为复杂,技术难度和实现复杂度较高

详细方案可以参考。

总结

在实际情况下,电商库存可能远比文章说的复杂,除了商品的总库存之外,一般还会有按照不同城市,不同仓库,不同门店等再结合下单渠道有针对性的进行库存管控。在这个过程中,非常容易出现库存扣减数据的不准确,可能是少卖了,也可能是多卖了,所以基于库存流水去构建库存核对机制就显得尤为重要了。

0 阅读:1

架构小魔方

简介:感谢大家的关注