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

9 篇文章 0 订阅

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

在多节点的项目中,经常要涉及到某些方法加锁的控制。而这个时候,简单易用的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模式来进行调度。

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

或者为每个请求设置超时时间,超时抛出异常。

 

 


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值