温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

分布式环境下怎样利用Redis实现分布式锁

发布时间:2021-11-15 14:48:33 来源:亿速云 阅读:158 作者:柒染 栏目:大数据

分布式环境下怎样利用Redis实现分布式锁,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。

在某些高并发的业务场景下,例如秒杀、选课等系统,为了避免出现商品超卖、选课人数超出课程规定人数的问题发生,读写数据库时需要进行加锁操作,保证某时刻已有一个用户在操作。在Java单机应用中,直接使用synchronized关键字没有任何毛病,但在分布式系统中就不行了,这时就需要引入分布式锁来解决问题。分布式锁可以用Zookeeper或Redis来实现,重点讲解使用Redis实现分布式锁。

    在Redis中有一个SETNX命令,如果key在Redis中存在,返回0,否则返回1,执行成功。下面是一种错误的实现分布式锁的思路,最后我会写一个正确的实现分布式锁的代码,请大家参考

错误的分布式锁思路

    假如客户1需要加锁时执行SETNX("key","value")返回1加锁成功,其余客户执行SETNX返回0没有获取锁,加锁失败会一直监听key并循环执行SETNX("key","value"),直到返回1。当客户1需要释放锁时需要执行DEL("key")释放锁。但这里有一个问题,如果客户1所在的进程挂掉后,key永远不会被删除,其余客户执行SETNX("key" ,"value")永远返回0,产生死锁,这样的分布式锁思路是错误的。

正确的思路

    如果客户进程获得锁后,设置一个超时移除的动作,如expire命令,客户进程挂掉后超时锁自动释放,其他客户任然可以获得锁。下面我用多线程来模拟高并发下的分布式锁的获取、释放。

    客户端获得锁:

        将k v通过SETNX命令存入Redis,如果返回1则表明Redis没有这条数据,操作成功获得锁,如果返回0则表明Redis中有这条   数据,其他客户端占有锁,获得锁失败,进入等待状态。

    RedisThread.java

分布式环境下怎样利用Redis实现分布式锁

模拟一个客户端

            如果getLock()方法返回true,则表明获得锁,执行后面的业务逻辑,最后通过DEL(k)命令释放锁。

            如果getLock()方法返回false,循环持续监听(当然也可以通过Thread.sleep()控制监听频率),直到获得锁后执行业务逻辑最后释放锁。

    RedisThread.java

分布式环境下怎样利用Redis实现分布式锁

开启多个线程模拟高并发

    RedisThread.java

  1. @Override  

  2.     public void run() {  

  3.         try {  

  4.             //调用客户端  

  5.             client();  

  6.         } catch (Exception e) {  

  7.             e.printStackTrace();  

  8.         }         

  9.     }  

RedisLock.java 测试

开启50个线程模拟50个客户(50个服务组成的集群)

分布式环境下怎样利用Redis实现分布式锁

输出结果如下:

lock-->业务开始-->业务结束-->unlock--lock-->.......

分布式环境下怎样利用Redis实现分布式锁

关于分布式环境下怎样利用Redis实现分布式锁问题的解答就分享到这里了,希望以上内容可以对大家有一定的帮助,如果你还有很多疑惑没有解开,可以关注亿速云行业资讯频道了解更多相关知识。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI