加锁时同样需要判断锁变量的值,根据锁变量值来判断能否加锁成功;释放锁时需要把锁变量值设置为 0,表明客户端不再持有锁。
基于单个 Redis 节点实现分布式锁
加锁:
释放锁:
SETNX 命令,对于不存在的键值对,它会先创建再设置值(也就是“不存在即设置”),为了能达到和 SETNX 命令一样的效果,Redis 给 SET 命令提供了类似的选项 NX,用来实现“不存在即设置”。如果使用了 NX 选项,SET 命令只有在键值对不存在时,才会进行设置,否则不做赋值操作。此外,SET 命令在执行时还可以带上 EX 或 PX 选项,用来设置键值对的过期时间。
SET key value [EX seconds | PX milliseconds] [NX]
// 加锁, unique_value作为客户端唯一性的标识
SET lock_key unique_value NX PX 10000
//释放锁 比较unique_value是否相等,避免误释放
if redis.call("get",KEYS[1]) == ARGV[1] then
return redis.call("del",KEYS[1])
else
return 0
end
基于多个 Redis 节点实现高可靠的分布式锁
我们来具体看下 Redlock 算法的执行步骤。Redlock 算法的实现需要有 N 个独立的 Redis 实例。接下来,我们可以分成 3 步来完成加锁操作。
- 第一步是,客户端获取当前时间。
- 第二步是,客户端按顺序依次向 N 个 Redis 实例执行加锁操作。
- 第三步是,一旦客户端完成了和所有 Redis 实例的加锁操作,客户端就要计算整个加锁过程的总耗时。客户端只有在满足下面的这两个条件时,才能认为是加锁成功。条件一:客户端从超过半数(大于等于 N/2+1)的 Redis 实例上成功获取到了锁;条件二:客户端获取锁的总耗时没有超过锁的有效时间。
在 Redlock 算法中,释放锁的操作和在单实例上释放锁的操作一样,只要执行释放锁的 Lua 脚本就可以了。
此文章为8月Day24学习笔记,内容来源于极客时间《redis核心技术与实战》