WMS如何满足防止超卖的需求

312 阅读5分钟

我司是专业提供仓储配送一体化服务的物流企业,全国拥有200+仓库。上游对接客户众多,需要满足不同的定制化服务,同时要为不同的业务方案提供兜底,缺货判断就是衍生需求之一。

需求背景

一般情况下,WMS管理仓库内实物库存OMS/ERP管理销售库存(也可能会建立库存中心)。WMS和OMS对接,对接方式可通过平台(例如阿里奇门)或接口直连(Http):OMS推送入库单、出库单或其他单据至WMS;WMS作业完成后,将作业结果回传至OMS;WMS管理仓库内实物库存。OMS可存储不同仓库(对于中大型企业会将货物分布至全国不同的仓库,以提高配送效率及客户体验)的库存信息,可根据销售订单选择将其推送至指定仓库。综合来看,这种管理方式具有一定的灵活性。
由于我司对接上游客户众多,其ERP服务商或自身信息化能力以及实现方案差异,部分客户要求WMS提供缺货判断需求,即OMS推送出库单至WMS时,如库存不足则提示缺货异常,再推送至其他仓库。

下发-回传.png

问题分析

缺货判断主要带来两方面的问题:一是接口性能;二是数据一致性。对于与外部直接交互的接口,接口性能及稳定性至关重要。特别是在电商大促活动期间,如出现接口超时,上游ERP会将订单推送至其他仓库,为企业带来直接的经济损失。在数据一致性方面,库存数据实时增量变更,在分布式环境下,需要保证服务间的数据实时一致且具有较高性能。

方案设计

根据业务需求的变化,在不同阶段采用了不同的实现方案,最终完整方案如下:

库存分层

在为满足一盘货需求时,我们将库存分层设计,分为:全网库存、分仓库存和库位库存。
库位库存:最小颗粒度库存,包括库区、库位、sku、批次属性、在库数量、可用数量、待移入数量、分配数量、冻结数量等信息。
分仓库存:指定货主在指定仓库的库存汇总信息。
全网库存:指定货主在所有仓库的库存汇总信息。

不同层次库存的数据一致性

数据同步时机

是否每次库位库存的变更,均触发全网库存和分仓库存的变更,答案是否定的。需要从业务域进行分析。库位库存反映的是仓内作业的结果;通常情况下,全网库存和分仓库存反映的是货主出入库作业指派的结果。可能还包括其他单据,例如加工单、拆套单、调整单等,即全网库位和分仓库存的变更是基于单据维度的,因为单据可作为上下游交互的凭据。

综上,全网库存和分仓库存是单据维度触发变更。单据是通过相应的任务驱动实际作业的,因此在实际业务中,为满足库存变更的及时性需求,任务完成后触发全网库存和分仓库存的变更。

不同类型的任务完成后,发送任务完成消息。全网库存和分仓库存业务域订阅相应任务完成消息,实现库存增量变更。

库存同步.png

库存同步幂等

库存同步接口必须实现幂等,否则在消息至少消费一次的特性下,会导致数据不一致。在实际作业环境中,通过增量更新的方式保证数据一致性是一项系统工程。由于业务场景(还包括正向流程和逆向流程)较多,最终还是会出现数据不一致的情况,为解决这种问题,增加了定时和手动的方式进行数据同步

解决方案

库存分层以及库位库存和全网库存、分仓库存的数据同步机制是方案的基础,必须保证全网库存和分仓库存的数据是可靠的,是否缺货是以全网库存和分仓库存数据进行判断的。

初步方案

出库单下发时,同步占用全网/分仓库存。

这种处理方式存在一定的问题:

  • 单据下发的核心除业务逻辑校验外,主要是单据创建,增加了全网/分仓库存占用的逻辑,接口性能下降
  • 在客户集中推送批量单(大部分sku相同)的情况下,全网/分仓库存占用的逻辑导致数据库层面锁资源竞争加剧接口性能急剧下降

最终方案

最终方案流程如下:

  • 初始化全网/分仓库存缓存:库存占用在Redis中执行。默认5分钟过期,防止缓存增量同步数据不一致。
  • 生成时间戳唯一版本号。
  • lua脚本占用缓存中库存:防止并发,有序更新缓存,保证缓存数据准确性。
  • 持久化出库单。
  • 生成全网/分仓库存占用请求:库存占用逻辑在缓存中执行,再通过占用请求批量更新至全网/分仓数据库库存(插入性能高于更新性能,空间换时间)。

时间戳唯一版本号

时间戳唯一序列号借鉴了分布式一致性算法的设计理念,保证唯一、顺序性,用作版本号。初始化缓存时,包含当前版本号汇总版本号,默认为0;执行缓存占用逻辑时,当前版本号更新,汇总版本号为历史版本号之和(包含当前版本号);在定时任务中,占用请求执行完毕后,会判断汇总版本号与缓存中汇总版本号对比,如果相同则刷新缓存并续期。汇总版本号主要用于解决请求执行中断,或占用请求持久化乱序问题。

占用请求同步.png