读库存扣减系列文章有感

微信公众号架构师之路最近发了一篇关于库存扣减文章引起了大家的广泛转发,作为一个小菜鸟,也发表点自己的菜鸟想法吧

这篇文章原文是库存扣多了,到底怎么整 ,后面还有一篇对网友回复的解答库存扣减还有这么多方案?

第一篇文章中着重描述了扣减库存的并发问题如何解决,如何保证幂等。

文章首先解决的是如何做到幂等,因为“扣减”库存一定是一个非幂等的操作,那么可以通过“设置”库存来解决,因为设置库存是一个幂等操作。

第二个解决的是幂等之后的并发问题,因为“设置”库存虽然做到了幂等但是并没有解决并发时带来的一致性问题,当两个用户同时“设置”库存是会造成数据的不一致。

紧接着就引出了CSA(“Compare And Set”),CSA本质上就是一种乐观锁方式---先比较再设置。每次扣减库存时都做比较,如果“当前库存”总数和“原库存”总数一致时才执行“扣减”,否则“扣减执行失败”,那么失败后只有两种办法,要么事务回滚,要么自动重试,如果重试后发现扣减后总数小于0那么就需要返回给用户错误了。

这两个思路非常的nice,分别解决了“幂等”和“一致”,但是没有引出“高并发”这个话题,因为高并发下这种方法失败的概率很大,会频繁失败给用户不好的体验。

后来很多网友就在后面引出了另外的一些观点,例如redis,利用了redis的“快”,redis的快有几个原因,第一是内存读取,第二是非阻塞IO,第三是单线程loop,避免了物理锁,减少线程上下文切换时间,第四是hash结构存储。因此虽然是单线程,但是redis带来非常高效率的读取,并且天然支持“高并发”,因为单线程操作不加任何锁。但是redis的另外一个风险就是数据存储在内存中,有丢失的风险。因此,使用时还需结合业务场景来看。

第一篇文章后面还有网友提到了使用队列来异步“扣减”,这实际上就和redis单线程一样了,这种方法思路挺好的,但是本菜鸟觉得会损失掉很多性能,是一种时间换空间的方案,可能会带来用户体验问题。

着重要提到的是后面一篇文章有一个答复思路非常新颖,因为这个问题的并发点实际上就是“库存”,所有的请求都在这个单点上操作,因此采用分布式的思路就是把这个“单点”均衡开,如果库存总数是m,那么将同一个key下的库存分成n组,k1...kn,每组的库存数为m/n,扣减时可以将请求均分到k1到kn上,这样就减少了冲突的几率,又是一种空间换时间的好方法!

最后本菜鸟想说的是,库存扣减这个问题往深了说在每一层可能都有不同的解决方案,在应用场景中应该按照具体的场景来看,是多读场景还是多写场景,用户的要求也不一定相同,因此业务场景决定了技术选型。这个话题还是非常值得探讨的,各种思路产生了火花,希望博主今后能多发些这种好文^_^

时间: 2024-11-05 14:47:50

读库存扣减系列文章有感的相关文章

自实现CAS原理JAVA版,模拟下单库存扣减

在做电商系统时,库存是一个非常严格的数据,根据CAS(check and swap)原来下面对库存扣减提供两种方法,一种是redis,一种用java实现CAS. 第一种 redis实现: 以下这个类是工具类,稍作修改就可运行 import java.util.regex.Pattern; import org.slf4j.Logger;import org.springframework.beans.factory.support.BeanDefinitionReader;import org.

库存扣减和订单自动失效

最近因为身体原因没怎么学习,深深的体会到身体才是最重要的.以后一定加强锻炼. 切入正题,最近项目中需要实现在线挂号功能,初步设计把排班生成的号源看做库存,挂的号看做一个个的订单,生成了订单自动锁号,十分钟不支付自动取消订单,退回号源. 排班那一套就不做详细说明了. 库存扣减和锁 初步设想有几种方案: 1.代码同步, 例如使用 synchronized,lock 等同步方法,看着貌似挺合理的. 但是synchronized 作用范围是单个jvm实例, 如果做了集群,分布式等,就没用了. 而且syn

读logback源码系列文章(五)——Appender --转载

原文地址:http://kyfxbl.iteye.com/blog/1173788 明天要带老婆出国旅游几天,所以这段时间暂时都更新不了博客了,临走前再最后发一贴 上一篇我们说到Logger类的info()方法通过层层调用,最后委托Appender来记录日志,这篇博客我们就接着说一下,Appender组件是怎么记录日志的 实际上Appender可能是logback框架中最重要的组件之一,虽然Logger是记录日志的接口,但是如果一个Logger没有关联到任何Appender的话,那么这个Logg

库存扣多了,到底怎么整

业务复杂.数据量大.并发量大的业务场景下,典型的互联网架构,一般会分为这么几层: 调用层,一般是处于端上的browser或者APP 站点层,一般是拼装html或者json返回的web-server层 服务层,一般是提供RPC调用接口的service层 数据层,提供固化数据存储的db 对于库存业务,一般有个库存服务,提供库存的查询.扣减.设置等RPC接口: 库存查询,stock-service本质上执行的是    select num from stock where sid=$sid 库存扣减,

EF+MySQL乐观锁控制电商并发下单扣减库存,在高并发下的问题

下订单减库存的方式 现在,连农村的大姐都会用手机上淘宝购物了,相信电商对大家已经非常熟悉了,如果熟悉电商开发的同学,就知道在买家下单购买商品的时候,是需要扣减库存的,当然有2种扣减库存的方式, 一种是预扣库存,相当于锁定库存, 一种是直接扣减库存. 我们采用的是预扣库存的方式,预扣库存的时候,在SalesInfo表中,将最大可售数量MaxSalesNum减去购买数量,用一条SQL语句来表示这个业务,就是下面这个样子的: update salesinfo set MaxSalesNum=MaxSa

????销售订单发运后的状态为:已发运; 下一步为:运行接口 。仓库库存没有扣减

销售订单发运后的状态为:已发运;下一步为:运行接口.仓库库存没有扣减 问题概述 在正常的销售订单发运处理后,在发运--事务处理中的行状态和下一步中分别为:已连接 不适用  但在这个销售订单发运处理后的行状态和下一步中分别为:已发运 运行接口  ,但运行接口后,还是这样,仓库中的现有量,还是存在,只是可处理量为 0 原因: 查了metalink,属于系统bug.Bug No. 4460875 处理方法 从后台表wsh_delivery_details的数据库中改OE_INTERFACED_FLAG

读:一个女孩从软件测试工程师到主管的成长历程 文章有感

今天我从网上读到了一篇文章,是一个女孩分享了她的成功经历:从一名软件测试工程师成为一名主管的奋斗历程.读了之后颇有感悟,分享上来希望与大家共享,也希望能给大家带来一些希望和激励.她从前是学经济贸易的,由于对测试行业的强烈兴趣,毕业后在北京学校学习软件测试工程专业.工作不到一年的时间里,她已经从测试员升职到测试主管了.对于学习.工作,她积累了许多点点滴滴的经验,所以她将这一年的经历写下来与大家分享. 原文章: 走入测试行业:兴趣.知识   说实话,我做测试工作的时间不是很长,学完软件测试工程师的课

php高级进阶系列文章--第二篇(PHP基础知识复习)

php基础知识复习 本文中对于简单的知识点只会提及一下(例如什么控制结构什么的),对于较有难度的详细复习下(例如面向对象的反射等等) 再次申明,本系列文章不是从最基础的开始复习,对于零基础的可能不适用,本文的初衷是我要准备攻读源码,在攻读前将之前的知识牢固下,太过简单的就写在文中了 1,echo print echo 可以输出一个或者多个字符串 print 只可以输出一个字符串,返回值总为1 2,PHP7中的组合比较符 echo 1 <==> 1 // 0 echo 1 <==>

读SRE Google运维解密有感(四)-聊聊问题排查

前言 这是读"SRE Google运维解密"有感第四篇,之前的文章可访问www.addops.cn来查看.今天我们来聊聊"问题排查"这个话题,本人到目前为止还在参与一线运维的工作,遇到过很多"稀奇古怪"的线上故障和问题,结合SRE中给出的一些方法,来说说"问题排查"那点事. 排查问题不是玄学 排查出线上问题,并找到根本原因加以解决,是一件很有成就感的事情,曾经有人问过我,"你是怎么想到问题出现在xxx的?又是怎么确认