Redis实现分布式锁

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

基于Redis实现分布式锁。分为单Redis节点实现和Redis集群实现。

基于单个Redis节点实现分布式锁

作为分布式锁实现过程中的共享存储系统Redis可以使用键值对来保护锁变量在接收和处理不同客户端发送的加锁的操作请求。

image

客户端A、C同时请求加锁因为Redis使用单线程处理请求所以即使客户端同时发起加锁请求Redis也会串行处理保证每次只有一个客户端加锁成功另一个客户端返回加锁失败。

客户端执行释放锁操作后Redis将锁的值改为0表明没有客户端持有锁。

加锁包含了三个操作分别是读锁变量、判断锁、把锁的值修改为1这三个操作在执行时需要保证原子性。可以使用单命令操作或者使用Lua脚本。

常用的但命令操作SETNX。它用于设置键值对的值。具体来说就是这个命令在执行时会判断键值对是否存在如果不存在就设置键值对的值如果存在就不做任何设置。

对于释放锁操作来说我们可以在执行完业务逻辑后使用 DEL 命令删除锁变量。不过你不用担心锁变量被删除后其他客户端无法请求加锁了。因为 SETNX 命令在执行时如果要设置的键值对也就是锁变量不存在SETNX 命令会先创建键值对然后设置它的值。所以释放锁之后再有客户端请求加锁时SETNX 命令会创建保存锁变量的键值对并设置锁变量的值完成加锁。

风险点就是如果客户端加锁后因为发生异常一直没有执行最后的释放锁操作锁就一直不能释放其他客户端就无法拿到锁无法正常执行业务。解决办法就是给锁变量设置一个过期时间即使客户端发生异常无法释放锁在锁变量过期后把它删除。

SET key value [EX seconds | PX milliseconds]  [NX]
基于多个Redis节点实现高可靠的分布式锁

在我们实现高可靠的分布式锁时就不能只依赖单个命令操作需要按照一定的步骤和规则进行加锁操作。否则就可能会出现锁无法工作的情况。其实就是分布式锁的算法。常见的分布式锁算法很多这里介绍RedLock。

Redlock 算法的基本思路是让客户端和多个独立的 Redis 实例依次请求加锁如果客户端能够和半数以上的实例成功地完成加锁操作那么我们就认为客户端成功地获得分布式锁了否则加锁失败。这样一来即使有单个 Redis 实例发生故障因为锁变量在其它实例上也有保存所以客户端仍然可以正常地进行锁操作锁变量并不会丢失。

实现步骤

  1. 客户端获取当前时间。
  2. 客户端按顺序依次向 N 个 Redis 实例执行加锁操作。
  3. 一旦客户端完成了和所有 Redis 实例的加锁操作客户端就要计算整个加锁过程的总耗时。

客户端只有在满足下面两个条件时才能认为加锁成功

  • 条件一客户端从超过半数的Redis实例上成功获取到了锁
  • 条件二客户端获取锁的总耗时没有超过锁的有效时间。

在满足了这两个条件后我们需要重新计算这把锁的有效时间计算的结果是锁的最初有效时间减去客户端为获取锁的总耗时。如果锁的有效时间已经来不及完成共享数据的操作了我们可以释放锁以免出现还没完成数据操作锁就过期了的情况。

学习来源极客时间 《Redis核心技术与实战》 学习笔记 Day20

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: redis

“Redis实现分布式锁” 的相关文章