redis实现分布式锁的几种方式 分布式锁的实现方式redis

关于这个redis实现分布式锁的几种方式(分布式锁的实现方式redis)很多人还不知道,现在让我们一起来看看吧!

redis实现分布式锁的几种方式 分布式锁的实现方式redis


1、为什么需要分布式锁?在谈论分布式锁之前,有必要解释一下为什么需要分布式锁 。与分布式锁相比,单机锁则相反 。当我们编写多线程程序时,我们避免了同时操作一个共享变量所导致的数据问题 。
2、通常,我们使用一个锁来互斥以保证共享变量的正确性,其使用范围是在同一个进程中 。如果有多个进程需要同时操作一个共享资源,它们怎么会互斥呢?现在的业务应用通常是微服务架构,这也意味着一个应用会部署多个流程 。如果多个进程需要修改MySQL中的同一行记录,为了避免乱序操作导致的脏数据,这时候就需要引入分布式锁 。
3、要实现分布式锁,我们必须使用一个外部系统,在这个系统中所有的进程都申请锁 。这个外部系统必须实现互斥,即当两个请求同时进来时,只有一个进程被成功锁定,另一个会失败 。这个外部系统可以是数据库,可以是Redis,也可以是Zookeeper,但是为了追求性能,我们通常会选择用Redis或者Zookeeper来做 。
4、Redis本身可以被多个客户端共享访问,恰好是一个共享存储系统,可以用来存储分布式锁 。而且Redis读写性能高,可以应对高并发锁操作场景 。本文主要讨论如何基于Redis实现分布式锁以及实现过程中可能出现的问题 。
5、如何实现分布式锁?Redis作为实现分布式锁过程中的共享存储系统,可以使用键-值对存储锁变量,接收和处理不同客户端发送的加锁和释放锁的操作请求 。那么,键值对的键和值是如何确定的呢?我们需要给锁变量一个变量名,用这个变量名作为键-值对的键,而锁变量的值就是键-值对的值 。这样Redis可以保存锁变量,客户端通过Redis的命令操作实现锁操作 。
6、要实现分布式锁,Redis必须是互斥的 。可以使用SETNX命令,意思是SETIFNOTEXIST,即如果键不存在,就设置它的值,否则什么都不做 。两个客户端进程可以执行这个命令实现互斥,可以实现分布式锁 。
7、下面展示了Redis如何使用键/值对来保存锁变量,以及两个客户机如何同时请求锁 。锁定操作完成后,成功锁定的客户端可以对共享资源进行操作,比如修改MySQL中的一行数据 。操作完成后,要及时释放锁,给后来者操作共享资源的机会 。
8、怎么开锁?使用DEL命令直接删除该键 。这个逻辑很简单,整个过程写成伪代码如下 。//加锁SETNXlock_key1//业务逻辑DOTHINGS//释放锁DELlock_key但是,上面的实现有一个很大的问题 。
9、当客户端1获得锁时,如果发生以下情况,将会导致死锁 。程序处理业务逻辑异常,没及时释放锁进程挂了,没机会释放锁以上情况会造成已经获取锁的客户端一直占用锁,其他客户端永远不会获取锁 。如何避免死锁为了解决上面的死锁问题,最简单的解决方案是在申请锁并在Redis中实现时为锁设置一个到期时间 。
10、假设操作共享资源的时间不会超过10s,那么在锁定的时候,设置密钥过期10s 。但是,上述操作仍然存在问题 。锁定和设置到期时间是两个命令 。
11、有可能只执行了之一个,而第二个失败了,例如:SETNX执行成功,执行EXPIRE时由于 *** 问题,执行失败SETNX执行成功,Redis异常宕机,EXPIRE没有机会执行SETNX执行成功,客户端异常崩溃,EXPIRE没有机会执行简而言之,如果这两个命令不能保证是原子操作,则存在到期时间设置失败的潜在风险,死锁仍可能发生 。好在Redis12以后,Redis扩展了SET命令的参数,在SET的同时指定了到期时间 。这个操作是原子的 。

推荐阅读