为什么需要分布式锁以及如何实现?

    作者:匿名更新于: 2021-10-24 21:44:24

    大神带你学编程,欢迎选课

      分布式锁在实际场景中,是比较常用的,也是面试经常涉及的。接下来,我们就来讨论一下,为什么我们需要分布式锁,以及分布式锁的实现,最后谈到了Redis来实现分布式锁,从而帮助我们了解分布式锁的实现。

      我们为什么需要分布锁

      对应于分布式锁的是「单机锁」,我们在编写多线程程序时,为了避免同时操作一个共享变量而产生数据问题,我们常常使用一把锁来「互斥」,以保证程序的正确性,其使用范围是在「同一个进程」中。

      假如换做是多个进程,需要同时运行一个共享资源,该如何互斥呢?

      举例来说,目前的业务应用通常是微服务架构,这也意味着一个应用程序部署多个进程,那么如果多个进程需要在MySQL中修改同一行的记录时,这个时候需要避免乱序从而导致数据错误,所以,我们可以引入「分布式锁」来解决这个问题。  

     

      要实现分布式锁,必须借助一个外部系统,所有进程都到这个系统上申请「加锁」。

      而且这个外部系统,必须要实现“互相排斥”的能力,也就是说两个请求同时进入,只能返回一个成功的进程,另一个返回失败(或等待)。

      而这个外部系统,它必须要可以实现「互斥」的能力,也就说,当两个请求同时进来时,只会给其中一个进程返回成功,而对于另一个进程,则返回失败(或等待)。

      这个外部系统,可以是MySQL,也可以是Redis或Zookeeper。

      接下来,主要是以Redis为主线,来帮助你看看如何实现。

      分布式锁怎么实现?

      我们从最简单的开始讲起。

      你想要实现分布锁,那么就是上面提到的,Redis要具备有「互斥」的能力,我们可以使用SETNX命令。该命令表示的是SET if Not eXists,即如果key不存在的时候,才会设置它的值,否则它什么都不做。

      两个客户端进程可以执行这个命令,达到互斥,就可以实现一个分布式锁。

      客户端1申请加锁,加锁成功:

      127.0.0.1:6379> SETNX lock 1

      (integer) 1 // 客户端1,加锁成功

      当客户端2也申请加锁时,因为它后到达,则会加锁失败:

      127.0.0.1:6379> SETNX lock 1

      (integer) 0 // 客户端2,加锁失败

      在这个时候,加锁成功的客户端,就可以去操纵「共享资源」了,比如,修改MySQL的某一行数据,或者调用一个API请求。

      在操作结束后,还要及时释放锁,让后来者有机会操作共享资源的机会。那么,怎样释放锁?

      同样简单,直接使用DEL命令删除此key即可:

      127.0.0.1:6379> DEL lock // 释放锁

      (integer) 1

      这一逻辑很简单,整个过程就是这样:  

     

      结尾

      本文主要对分布式锁的重要性,以及使用Redis来实现分布式锁进行了讲解,我们要了解分布式锁的作用,以及实现分布式锁的重点是什么,最后再对Redis的实现加以理解,从而帮助大家了解分布式锁的实现。

        >>>>>>点击进入Python专题

课课家教育

未登录