库存系统实现

前言

最近在重构之前系统中的库存处理逻辑。 老的系统中库存处理逻辑只是一个类里面的几个方法,同时是直连DB操作,有缓存处理,但是在数据一致性保障上并没有特别的可靠。 随着运营投入的越来越多,新的运营策略在产品表现上会出现大库存情况,比如引入package的方式,这样原有的库存处理逻辑的QPS就需要变为百倍了,在高峰期对于数据库系统的写QPS是很大的压力,同时系统不能简单的通过机器扩容或者横向扩展解决,所以需要将库存处理逻辑单独到独立的服务系统中进行解决。

业界方案

阿里在数据一致性的处理上采用了数据库方案,当然为处理高并发写入,阿里有能力在数据库角度进行了优化,可以支持高并发写入和事务控制,一般公司不具备这样的技术能力,需要在业务层进行显示控制。

系统关键点

考虑基于DB解决数据一致性问题,首先要解决单点瓶颈和数据过多造成的数据倾斜问题。

同时系统需要考虑单元化场景下的库存扣减逻辑,核心逻辑在于库存扣减是否和用户产生直接关系。

事务控制

由于不具备数据库层面的高并发事务控制,需要在系统层面进行实现。

采用乐观锁 整个加锁时间

start transaction
lock budget record and get its value
subtract budget record by
insert business orders...
commit 

通过sql层面更新取代先读后更新逻辑。

SQL优化批量处理 SQL组合在一起,和DB一次交互,更新语句保持条件更新,保证更新后余额大于等于0。 SQL添加commit_on_success(减少commit请求网络交互),target_affect_row 1标签。

系统分片

单个数据库无法支撑高并发写入,考虑“桶拆分”,根据userId进行分桶,子桶配额不足时,路由到主桶。 主桶和子桶按比例分配,子桶适合时机回收。

设置分桶阈值,自动分桶,同时基于日志流水(定时任务)进行分桶合并,异步将库存分桶合并到主桶。可降低更新频率,只在合并时发生更新一次,通过定时任务消除分桶碎片,定时任务进行补偿。

分布式事务

库存扣减设计到下游多个服务聚合,需要保证事务一致性,在一个下游服务失败后可以主动感知。

  • 两阶段提交:方案过于悲观,放弃。
  • 设计基于轻消息组件,引入事件记录,保证事件记录和数据操作在一个DB事务中,基于消息实现事件通知,事务1失败,进行反向扣减处理(都只是预操作),第二阶段进行整体事务commit,方案需引入minibus方案。

结论

基于以上方案重构库存系统服务,单记录(子桶)维持在8kqps,摸高到1w+qps,32个子库压测达30wQPS性能。

猜你喜欢

转载自my.oschina.net/u/1000241/blog/2986439