美文网首页IT@程序员猿媛程序员
高并发下一致性的一点思考

高并发下一致性的一点思考

作者: 半亩房顶 | 来源:发表于2019-03-20 21:47 被阅读0次

引言

在高并发的分布式环境下,对于数据的查询与修改容易引发一致性问题,本文将分享一种非常简单但有效的优化方法。

一、业务场景

业务场景为,购买商品的过程要对余额进行查询与修改,大致的业务流程如下:

(1)从数据库查询用户现有余额 SELECT money FROM t_yue WHERE uid=$uid,不妨设查询出来的$old_money=100

(2)业务层实施业务逻辑,比如购买一个80元的商品,并且打九折

if($old_money> 80*0.9) $new_money=$old_money-80*0.9=28

(3)将数据库中的余额进行修改 UPDAtE t_yue SET money=$new_money WHERE uid=$uid

在并发量低的情况下,这个流程没有任何问题,原有金额100元,购买了80元的九折商品(72元),剩余28元。

二、潜在的问题

在分布式环境中,如果并发量很大,这种“查询+修改”的业务很容易出现数据不一致。极限情况下,可能出现这样的异常流程:

(1)业务1和业务2同时查询余额,是100元

(2)业务1和业务2进行逻辑计算,算出各自业务的余额,假设业务1算出的余额是28元,业务2算出的余额是38元

(3)业务1对数据库中的余额先进行修改,设置成28元。

业务2对数据库中的余额后进行修改,设置成38元。

此时异常出现了,原有金额100元,业务1扣除了72元,业务2扣除了62元,最后剩余38元。

三、问题原因

高并发环境下,对同一个数据的并发读(两边都读出余额是100)与并发写(一个写回28,一个写回38)导致的数据一致性问题。

四、原因分析

业务1的写回:原有金额100,这是一个初始状态,写回金额28,理论上只有在原有金额为100的时候才允许写回成功,这一步没问题。

业务2的写回:的原有金额10038100的时候才允许写回成功,可实际上,这个时候数据库中的金额已经变为28了,这一步的写操作不应该成功。

五、简易解决方案

在set写回的时候,加上初始状态的条件compare,只有初始状态不变时,才允许set写回成功,这正是大家常说的“Compare And Set”(CAS),是一种常见的降低读写锁冲突,保证数据一致性的方法。

六、业务的升级

业务线使用CAS解决高并发时数据一致性问题,只需要在进行set操作时,compare一下初始值,如果初始值变换,不允许set成功。

对于上文中的业务场景,只需要将UPDAtEt_yue SET money=$new_money WHERE uid=$uid升级为UPDAtE t_yue SETmoney=$new_money WHERE uid=$uid AND money=$old_money即可。
并发操作发生时:
业务1执行 UPDAtE t_yue SET money=28 WHERE uid=$uid AND money=100
业务2执行 SET money=38 WHERE uid=$uid

【这两个操作同时进行时,只能有一个执行成功】。

七、怎么判断哪个执行成功,哪个执行失败

set操作,其实无所谓成功或者失败,业务能通过affect rows得知哪个修改没有成功:
执行成功的业务,为1
执行失败的业务,为0

八、总结

高并发“查询并修改”的场景,可以用CAS(Compare and Set)的方式解决数据一致性问题。对应到业务,即在set的时候,加上初始条件的比对。

相关文章

  • 聊聊高并发(六)实现几种自旋锁(一)

    在聊聊高并发(五)理解缓存一致性协议以及对并发编程的影响 我们了解了处理器缓存一致性协议的原理,并且提到了它对并发...

  • 高并发与缓存

    本文主要讲述高并发下缓存会出现的问题。 在高并发下,缓存会出现的问题有:缓存一致性、并发问题、穿透问题、缓存的雪崩...

  • 如何保持MySQL和Redis的一致性

    一、一致性问题 在高并发的业务场景下,数据库大多数情况都是用户并发访问最薄弱的环节。所以,就需要使用redis做一...

  • 高并发下一致性的一点思考

    引言 在高并发的分布式环境下,对于数据的查询与修改容易引发一致性问题,本文将分享一种非常简单但有效的优化方法。 一...

  • 高并发高可用系统以及面试分析

    1.高并发,高可用系统的一些思考 高并发依赖于场景和逻辑 不一定每个场景都会产生高并发,不要为了高并发而盲目的设计...

  • 可以说是全网最全的高并发架构设计笔记了,啃透了面试再问就吊打

    所谓的高并发,如果你要理解这个问题呢,其实就得从高并发的根源出发,为啥会有高并发?为啥高并发就很牛逼?我说的浅一点...

  • 如何设计一个秒杀系统

    系统要求 高性能 秒杀涉及大量的并发读和并发写,因此要求性能必须高; 一致性 秒杀中商品减库存的实现方式同样关键。...

  • 如何设计秒杀系统学习笔记.md

    秒杀系统架构设计都有哪些关键点 秒杀其实主要解决两个问题 一个是并发读 一个是并发写; 架构上的高可用、一致性和高...

  • 对高并发的思考

    近期很长的一段时间,都在学习总结,什么是高并发,怎么样实现高并发,接触了解的内容包括Nginx工作原理,Tomca...

  • mysql主从复制与读写分离

    一、mysql主从复制的思考 在高并发的时候,实现读写分离可以支撑更高的读并发的压力,在很多情况下,都是读多写少。...

网友评论

    本文标题:高并发下一致性的一点思考

    本文链接:https://www.haomeiwen.com/subject/mxsxvqtx.html