MyException - 我的异常网
当前位置:我的异常网» 互联网 » 互联网络一致性架构设计 - 库存扣除一致性

互联网络一致性架构设计 - 库存扣除一致性

www.MyException.Cn  网友分享于:2013-09-28  浏览:0次
互联网一致性架构设计 -- 库存扣除一致性

互联网一致性架构设计 -- 库存扣除一致性

 

 

业务复杂、数据量大、并发量大的业务场景下,典型的互联网架构,一般会分为这么几层:


  • 调用层,一般是处于端上的browser或者APP
  • 站点层,一般是拼装html或者json返回的web-server层
  • 服务层,一般是提供RPC调用接口的service层
  • 数据层,提供固化数据存储的db

 

 

 

 

扣除库存的过程

 

对于库存业务,一般有个库存服务,提供库存的查询、扣减、设置等RPC接口:

 

    1. 库存查询,stock-service本质上执行的是

        select num from stock where sid=$sid

 

    2. 库存扣减,stock-service本质上执行的是

        update stock set num=num-$reduce where sid=$sid

 

    3. 库存设置,stock-service本质上执行的是

        update stock set num=$num_new where sid=$sid

 

 

 

用户下单前,一般会对库存进行查询,有足够的存量才允许扣减:

 

    例如:总库存 = 5

 

 

用户下单时,接着会对库存进行扣减:

 

    例如:扣除3个商品,剩余2

 

 

 

 

 

容错机制

 

       架构在容错性上,往往需要一次重做,以防第一次扣除失败,就会调用重做来弥补。

 

       重试时,有可能会出现重复扣除,如果数据库层面有重试容错机制,可能导致一次扣减执行两次,最终得到一个负数的错误库存。



 

    原因:因为“扣减”操作是一个非幂等的操作,不能够重复执行。

 

    解决方法:将扣除改成设置。

 


 

     同样是购买3单位的商品,通过设置库存操作,即使有重试容错机制,也不会得到错误的库存,设置库存是一个幂等操作。

 

 

 

 

 

高并发下扣除商品

 

    查询


 

 

    并发购买

 

  • 用户1购买了3个库存,于是库存要设置为2
  • 用户2购买了2个库存,于是库存要设置为3
  • 这两个设置库存的接口并发执行,库存会先变成2,再变成3,导致数据不一致(实际卖出了5件商品,但库存只扣减了2,最后一次设置库存会覆盖和掩盖前一次并发操作)

 

   

    原因:设置操作发生的时候,没有检查库存与查询出来的库存有没有变化。

 

    解决方法:修改设置的sql

 

    修改前:

    update stock set num=$y where sid=$sid

    修改后:

    update stock set num=$num_new where sid=$sid and num=$num_old

 

    这正是大家常说的“Compare And Set”(CAS),是一种常见的降低读写锁冲突,保证数据一致性的方法。

 

 

 

 

其他解决方法

 

    1. 数据一致性:通常方法是使用乐观锁解决(时间戳、版本号)

 

    2. 可以用redis的事务性解决扣除库存问题,但是小心数据丢失,实际使用还要看业务

 

    3. 能否用事务解决?容易死锁,而且吞吐量低,不建议。

 

    4. 能否用分布式锁,如:setnx、mc、zookeeper?可以,但是吞吐量高不高?

 

    5. 使用队列,在数据库侧串行化执行,降低锁冲突。

 

 

 

 

 

文章评论

2013年中国软件开发者薪资调查报告
2013年中国软件开发者薪资调查报告
老程序员的下场
老程序员的下场
Java 与 .NET 的平台发展之争
Java 与 .NET 的平台发展之争
那些性感的让人尖叫的程序员
那些性感的让人尖叫的程序员
程序员的鄙视链
程序员的鄙视链
程序员眼里IE浏览器是什么样的
程序员眼里IE浏览器是什么样的
每天工作4小时的程序员
每天工作4小时的程序员
当下全球最炙手可热的八位少年创业者
当下全球最炙手可热的八位少年创业者
如何成为一名黑客
如何成为一名黑客
为什么程序员都是夜猫子
为什么程序员都是夜猫子
如何区分一个程序员是“老手“还是“新手“?
如何区分一个程序员是“老手“还是“新手“?
要嫁就嫁程序猿—钱多话少死的早
要嫁就嫁程序猿—钱多话少死的早
中美印日四国程序员比较
中美印日四国程序员比较
Web开发人员为什么越来越懒了?
Web开发人员为什么越来越懒了?
程序员必看的十大电影
程序员必看的十大电影
初级 vs 高级开发者 哪个性价比更高?
初级 vs 高级开发者 哪个性价比更高?
科技史上最臭名昭著的13大罪犯
科技史上最臭名昭著的13大罪犯
鲜为人知的编程真相
鲜为人知的编程真相
Google伦敦新总部 犹如星级庄园
Google伦敦新总部 犹如星级庄园
10个调试和排错的小建议
10个调试和排错的小建议
亲爱的项目经理,我恨你
亲爱的项目经理,我恨你
写给自己也写给你 自己到底该何去何从
写给自己也写给你 自己到底该何去何从
老美怎么看待阿里赴美上市
老美怎么看待阿里赴美上市
2013年美国开发者薪资调查报告
2013年美国开发者薪资调查报告
我的丈夫是个程序员
我的丈夫是个程序员
程序员的一天:一寸光阴一寸金
程序员的一天:一寸光阴一寸金
漫画:程序员的工作
漫画:程序员的工作
程序员都该阅读的书
程序员都该阅读的书
编程语言是女人
编程语言是女人
不懂技术不要对懂技术的人说这很容易实现
不懂技术不要对懂技术的人说这很容易实现
我是如何打败拖延症的
我是如何打败拖延症的
什么才是优秀的用户界面设计
什么才是优秀的用户界面设计
总结2014中国互联网十大段子
总结2014中国互联网十大段子
Java程序员必看电影
Java程序员必看电影
5款最佳正则表达式编辑调试器
5款最佳正则表达式编辑调试器
60个开发者不容错过的免费资源库
60个开发者不容错过的免费资源库
10个帮程序员减压放松的网站
10个帮程序员减压放松的网站
程序员最害怕的5件事 你中招了吗?
程序员最害怕的5件事 你中招了吗?
团队中“技术大拿”并非越多越好
团队中“技术大拿”并非越多越好
我跳槽是因为他们的显示器更大
我跳槽是因为他们的显示器更大
代码女神横空出世
代码女神横空出世
做程序猿的老婆应该注意的一些事情
做程序猿的老婆应该注意的一些事情
程序员周末都喜欢做什么?
程序员周末都喜欢做什么?
为啥Android手机总会越用越慢?
为啥Android手机总会越用越慢?
程序员和编码员之间的区别
程序员和编码员之间的区别
一个程序员的时间管理
一个程序员的时间管理
程序猿的崛起——Growth Hacker
程序猿的崛起——Growth Hacker
 程序员的样子
程序员的样子
“肮脏的”IT工作排行榜
“肮脏的”IT工作排行榜
软件开发程序错误异常ExceptionCopyright © 2009-2015 MyException 版权所有