杨开振
2016-10-28 01:56
作为java的多年经验的码农觉得老师的东西很怪异,CAS原理都不讲的,你用mysql的锁去应对秒杀基本就死在哪里了。
1、老师说得这个行锁很怪异,mysql根本就没有这个东西,没有加for update你会有行锁吗?不知道老师所谓的行锁是从天而降吗??这个称为悲观锁。但是代价太大,我们基本不用。因为使用它,你所有的线程就等着挂起和等待了,系统就基本就死在哪里了。
2、一般我们即时使用数据库,也不会这样用,应该加一个version字段。
(1)首先是程序读取select version, left from table;
(2)然后记录version字段(旧值),判定left - buyCount(购买数量)>=0,如果否退出,结束业务。否则继续(3)
(3)开始执行减库存
update table set left = left - #{byCount} , version = version+1
where count >0 and vesion = #{vesion}//这个version是旧值,而更新一次成功version就加1
这里数据库并没有任何锁,但是这里巧妙的使用了version字段,符合一个CAS原理,就是我当初读出的version(旧值)和实时数据库的version(当前需要更新时刻的实时值)是否一致,如果一致,则我会认为这条记录没有被其他线程修改,则减库存成功,如果不一致则我会认为其他线程修改过这个记录。就不会进行操作这个被称为乐观锁。这个时候我们会考虑重入,重复执行(1)-(3)步骤直至(2)的退出或者(3)成功继续我们的操作,这样就是一个没有锁的机制。这就是一个乐观锁的机制,而没有任何等待的机制,是一个非阻塞的过程。
3、企业的秒杀目前应该考虑使用redis,而不是mysql。
别和我说你mysql的性能和redis比,个人自测分别批量插入数据:
redis每秒在我的机子可以执行40万次的插入,而mysql只能执行不到2万次。这个性能差了几十倍。你用mysql是自己找麻烦。这个级别根本不同级,其次redis提供的事务很好的符合了秒杀的功能。
首先任何线程执行redis的操作的时候都是使用lua语言,redis在执行lua语言的时候是原子性的,让它执行减库存,并且记录用户购买记录。
直至秒杀时间到期或者库存为0,才考虑将redis缓存的数据批量一次性把减库存和用户购买的信息批量写入mysql。整个秒杀过程基本在redis完成,而不是数据库,不是你mysql的性能可比的,你服务器上mysql一秒可以4万次,redis可以上百万次,你怎么比??
秒杀场景主要两个点:
1:流控系统,防止后端过载或不必要流量进入,因为慕课要求课程的长度和简单性,没有加。
2:减库存竞争,减库存的update必然涉及exclusive lock ,持有锁的时间越短,并发性越高。
CAS是否适用瞬时竞争?
1:"select version, left from table where pk= {pid}"不加 for update 并发得到共享version
2: "update table set left = left - #{byCount} , version = version+1 where pk={id} count >0 and vesion = #{vesion}" 首先这句sql本身会加row-level exclusive lock。version大量冲突导致减库存失效,客户端重试导致TPS翻倍,加重DB负担。
3:对于使用redis+LUA实现秒杀库存逻辑,重点在异步MQ落地可靠性和异常回滚机制。
对于生产环境的秒杀没有这么简单,需要全链路梳理和优化,参见之前同事的分享:http://www.infoq.com/cn/presentations/challenge-of-alipay-red-envelopes
最后,不用回我了,如果你觉得我讲的问题多,希望你也录一个课程,这样可以帮助大家,何乐不为呢。
首先感谢你的回复,这门课已经说了,用最常用的技术分析实现秒杀场景。
其次你的思路请在想想。参考一下文档:
http://dev.mysql.com/doc/refman/5.7/en/innodb-locking.html
http://www.infoq.com/cn/presentations/seckill-solution-based-sql
http://geek.csdn.net/news/detail/93986
作者之前就在阿里淘宝技术部,秒杀处理方式我还是比较清楚的。
最后这门课只是帮助有需要的同学。
mysql的默认RR级别,对于写写操作,不是默认加行锁吗?这个人问了一大段的结果问题就是错的
mysql执行update语句的时候已经获得了这条记录的排它锁了 也就是老师说的行级锁吧
杨开振你这妖孽写完书来这儿砸场子
Java高并发秒杀API之高并发优化
78690 学习 · 182 问题
相似问题