高并发场景下的redis分布式锁失效-Timer线程解决推荐redisson框架完美解决 - Go语言中文社区

高并发场景下的redis分布式锁失效-Timer线程解决推荐redisson框架完美解决


1.建立一把redis分布式下的超时锁
Boolean result=StringRedisTemplate.opsForValue().setIfAbsent(lockKey,“value1”,10,TimeUnit.SECOND);
if(!result)
{return “error”;
}
问题1:如果业务执行的时间超过了锁的时间,出现锁失效的问题–第一个进程进来执行业务时候,锁突然超时了,这时候第二个业务进来了,此时第一个释放锁的时候释放的是第二个进程的锁,依次类推。。。
解决方法:创建一个客户端的识别的锁
String clientID=UUID.randomUUID().toString();
Boolean result=StringRedisTemplate.opsForValue().setIfAbsent(lockKey,clientID,10,TimeUnit.SECOND);
try{}
finally
{
if(clientID.equals(stringRedisTemplate().opsForValue().get(lockKey)))
{stringRedisTemplate.delete(lockKey)
}
}

问题2:
以上解决方法在高并发场景下会出问题,比如锁定超时60s,用户体验不行。
解决方法:利用timer给锁的超时时间续命(起一个分线程),比如隔10s,重新设置这把锁的超时时间
推荐redisson框架来实现(上述分线程的解决方法,redisson中利用类似timer操作防止死锁,redisson还可实现可重入锁–同一个线程不用等待相同的线程释放锁可以直接拿到该锁)
String lockKey=“lockKey”;
RLock redissonLock = redisson.getLock(lockKey);
try
{
redissonLock.lock();
业务代码;
}finally{
redissonLock.unlock();
}

在这里插入图片描述
问题3:如上图,如果再redis的master上设置完的锁后,突然宕机了,还没有往slave节点同步,怎么处理?

问题4:
redissonLock.lock(); 这个锁其实把请求变成了串行执行了,尽管redis的qps再高性能的服务器上能达到10万的qps,但是如果想更大的并发量提升个几十倍?

下图即解决问题3和问题4,其中问题3,如果不是非要用redis来做的话,还可以用zookeeper来保证主从的leader特性来保证同步性。但是性能不如redis好。如果非要用redis则用下图的redlock(不推荐使用redlock,还有写bug,如果用的话借助redisson框架来实现redis的分布式锁)来解决问题3,强烈建议使用zookeeper来创建分布式锁,充分利用zookeeper的leader选举机制来保证master的高可用性

在这里插入图片描述

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_28358461/article/details/103554667
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2021-05-19 08:46:03
  • 阅读 ( 1676 )
  • 分类:Linux

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢