当前位置: 首页 > 科技观察

有那么多去库存计划吗?

时间:2023-03-17 12:19:11 科技观察

昨天的一篇文章《库存扣多了,到底怎么整》,核心观点是:用“定库存”代替“减库存”,保证幂等性。使用CAS乐观锁,在“设置库存”时加入原始库存对比,避免数据不一致,我认为两个核心点应该是没有歧义的。结果很多朋友都说方案不好。今天分享一下接下来回复的一些计划和一些个人的看法。评论1updatestocksetnumnum=num-$countwheresid=$sidandstock>=$count;的方法可以吗?用来抵扣存货?答:该方案不能保证幂等性,可能会出现重复推导的情况。消息2把库存放在reids中,利用redis的事务性来扣减库存。分析:redis是如何实现事务操作的?本质也是乐观锁。在redis客户端执行:$num=GETkey$num=$num-$countSETkey$num当并发量大的时候,会遇到和《库存扣多了,到底怎么整》文章一样的并发一致性问题。redis的WATCH和EXEC可以提供一种类似事务的机制:WATCH观察key是否被改变。如果提交时更改了key,EXEC会返回null,表示交易失败。保证一致性的库存扣减可以这样执行:WATCHkey$num=GETkey$num=$num-$countMULTISETkey$numEXECWATCH后EXEC执行前,如果key的值发生变化,EXEC会失败。为什么redis的WATCH可以保证事务性,本质上是使用了乐观锁CAS机制。大多数情况下,不同的redisclient会访问到不同的key,所以WATCH发生碰撞的概率会比较小。在秒杀的业务场景下,即使使用了WATCH,调用方仍然需要重试。在CAS机制上,redis相比mysql并没有额外的优势。redis的高性能是由于redis内存访问和mysql数据存储的不同造成的。内存访问的缺点是数据“易失”,如果重启,数据可能会丢失。当然redis也可以把数据固化。每次都要刷盘吗?Redis确实不能当mysql来用。***,redis使用单线程避免了物理锁,但是mysql多线程也有多线程并发的优势。答:可以使用redis的事务性扣库存,但是在CAS机制上比mysql没有优势。高性能是由于其内存存储,副作用是数据丢失的风险。如何使用取决于业务Compromise(任何脱离业务的架构设计都是耍流氓)。Message3支持幂等性可以使用clienttoken和业务流吗?能否使用时间戳和版本号来确保一致性?答:是的。Message4能否在数据库端使用队列串行执行,减少锁冲突?答:是的。消息5可以使用事务吗?答:容易死锁,吞吐量很低,不推荐。评论6能不能用分布式锁,比如setnx,mc,zookeeper?答:可以,但是吞吐量真的高吗?评论7侧重于幂等性和一致性,但没有深入讨论高吞吐量。使用缓存来抵抗读请求,使用水平扩展来提高性能,是提高吞吐量的根本解决方案。回复:非常中肯。【本文为专栏作者《58神剑》原创稿件,转载请联系原作者】点此阅读更多该作者好文