码迷,mamicode.com
首页 > 数据库 > 详细

深入理解Spring Redis的使用 (九)、通过Redis 实现 分布式锁 的 BUG,以及和数据库加锁的性能测试

时间:2015-09-12 17:39:47      阅读:176      评论:0      收藏:0      [点我收藏+]

标签:

在多节点的项目中,经常要涉及到某些方法加锁的控制。而这个时候,简单易用的synchronized已经不能满足多节点的部署结构。

之前在项目中,用的比较多的是数据库的更新锁:for udpate。但是这个有个缺点,就是对于本来就容易出现瓶颈的数据库,造成了更大的压力。同时,如果是锁表的语句,同时表数据量特别大,基本服务器直接宕机了。

所以,决定绕开数据库,直接使用Redis来实现分布式锁。查了下资料,找到一些文章,思路都一致:

http://www.jeffkit.info/2011/07/1000/

http://my.oschina.net/u/1995545/blog/366381

于是参考文章,通过Spring aop注解方法来实现对方法的多节点加锁。

 

之前的文章给了实现的代码。并没有什么难度,注解+AOP。

但是今天做压力测试的时候,发现这个大有问题。

 

测试环境:

1000线程,每个线程执行1次。(这种更接近真实的tomcat环境)

 

sleep时间和执行时间:

* 20ms 约等于cpu线程切换时间,59998
* 50ms 43177
* 100ms 20555
* 150ms 7014
* 200ms 2970 性能尚可

但是,如果设置200ms,有可能有些线程,从最开始阻塞不断sleep,到最后全部结束了,才拿到锁。如果程序不结束,那么该线程就一直堵死,无法预料究竟多久能拿到锁。如果去设置等待多久超时断开,那么频繁的失败,对于用户肯定是无法接受的。

于是又测试数据库的锁

一张70W数据的表,

通过pk行级锁,执行时间1163(需要被锁数据存在的情况下,才能加上对应的锁),而且如果是每个线程都是各自的数据行的话,相互不阻塞会更快.(SSD固态硬盘。。。)

通过其他列表锁,一秒执行一次的感觉,直接卡死,停止测试

 

所以,通过sleep来等待,并发高的情况下,将会导致某些线程失控。

但是wait notify,又是针对单节点下才能使用。

 

也可以做到最细粒度,然后再用redis加锁,这样,降低线程堵死的可能性。

 

总结:

要么使用阻塞的方式来调度线程,

要么就实现一个可以在分布式环境下的类似NIO的reactor模式来进行调度。

保证先入先出,即使有些慢的状态下,不至于先来的反而堵死,造成差的用户体验。

 

 

 

深入理解Spring Redis的使用 (九)、通过Redis 实现 分布式锁 的 BUG,以及和数据库加锁的性能测试

标签:

原文地址:http://www.cnblogs.com/luochengqiuse/p/4802989.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!