Redlock原理简介和实现过程

2020-06-15  本文已影响0人  平凡人笔记

前言

上篇文章介绍了通过

SET key_name my_random_value NX PX 30000
NX 表示if not exist 就设置并返回True,否则不设置并返回False
PX 表示过期时间用毫秒级, 30000 表示这些毫秒时间后此key过期

方式实现的redis分布锁

但有缺点:

只作用在一个Redis节点上,即使Redis通过sentinel保证高可用,如果这个master节点由于某些原因发生了主从切换,那么就会出现锁丢失的情况:

在Redis的master节点上拿到了锁;

但是这个加锁的key还没有同步到slave节点;

master故障,发生故障转移,slave节点升级为master节点;

导致锁丢失。

由此 redis官方推荐 redlock 来解决这个问题

使用场景

多个服务间保证同一时刻同一时间段内同一用户只能有一个请求(防止关键业务出现并发攻击)

优点

概念说明

最低保证分布式锁的有效性及安全性的要求

使用redession实现分布锁的过程

假设有5个完全独立的redis主服务器

代码实现

maven依赖

<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.4.3</version>
</dependency>

获取redession客户端连接

业务处理接口

具体的业务逻辑实现都需要实现该接口

封装锁管理接口

锁管理接口实现类

调用加锁

redessoin获取锁和释放锁源码分析

获取锁

跟踪RLock类的lock.tryLock(100, lockTime, TimeUnit.SECONDS);方法

可以找到方法
现在来分析下其中的lua脚本

if (redis.call('exists', KEYS[1]) == 0)

首先分布式锁的KEY不能存在,,

then redis.call('hset', KEYS[1], ARGV[2], 1);

如果确实不存在,那么执行hset命令(hset REDLOCK_KEY uuid+threadId 1)

redis.call('pexpire', KEYS[1], ARGV[1]);

并通过pexpire设置失效时间(也是锁的租约时间)

if (redis.call('hexists', KEYS[1], ARGV[2]) == 1)

如果分布式锁的KEY已经存在,并且value也匹配,表示是当前线程持有的锁,

then redis.call('hincrby', KEYS[1], ARGV[2], 1);
redis.call('pexpire', KEYS[1], ARGV[1]);

那么重入次数加1,并且设置失效时间

return redis.call('pttl', KEYS[1])

获取分布式锁的KEY的失效时间毫秒数

释放锁

if (redis.call('exists', KEYS[1]) == 0)
then redis.call('publish', KEYS[2], ARGV[1])

如果分布式锁KEY不存在,那么向channel发布一条消息

if (redis.call('hexists', KEYS[1], ARGV[3]) == 0)
then return nil

如果分布式锁存在,但是value不匹配,表示锁已经被占用,那么直接返回

local counter = redis.call('hincrby', KEYS[1], ARGV[3], -1);

如果就是当前线程占有分布式锁,那么将重入次数减1

if (counter > 0) then redis.call('pexpire', KEYS[1], ARGV[2]);

重入次数减1后的值如果大于0,表示分布式锁有重入过,那么只设置失效时间,还不能删除

return 0; else redis.call('del', KEYS[1]);
redis.call('publish', KEYS[2], ARGV[1]);

重入次数减1后的值如果为0,表示分布式锁只获取过1次,那么删除这个KEY,并发布解锁消息

DEMO源码

https://gitee.com/pingfanrenbiji/redis-demo

参考文章

https://www.cnblogs.com/rgcLOVEyaya/p/RGC_LOVE_YAYA_1003days.html
https://yq.aliyun.com/articles/674394
上一篇 下一篇

猜你喜欢

热点阅读