读库存扣减系列文章有感

微信公众号架构师之路最近发了一篇关于库存扣减文章引发了你们的普遍转发,做为一个小菜鸟,也发表点本身的菜鸟想法吧redis

 

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

 

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

 

文章首先解决的是如何作到幂等,由于“扣减”库存必定是一个非幂等的操做,那么能够经过“设置”库存来解决,由于设置库存是一个幂等操做。并发

第二个解决的是幂等以后的并发问题,由于“设置”库存虽然作到了幂等可是并无解决并发时带来的一致性问题,当两个用户同时“设置”库存是会形成数据的不一致。异步

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

 

这两个思路很是的nice,分别解决了“幂等”和“一致”,可是没有引出“高并发”这个话题,由于高并发下这种方法失败的几率很大,会频繁失败给用户很差的体验。高并发

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

 

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

 

着重要提到的是后面一篇文章有一个答复思路很是新颖,由于这个问题的并发点实际上就是“库存”,全部的请求都在这个单点上操做,所以采用分布式的思路就是把这个“单点”均衡开,若是库存总数是m,那么将同一个key下的库存分红n组,k1...kn,每组的库存数为m/n,扣减时能够将请求均分到k1到kn上,这样就减小了冲突的概率,又是一种空间换时间的好方法!spa

 

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

相关文章
相关标签/搜索