redission 公平锁图解

226 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第7天,点击查看活动详情

1 前言

研究源码 是为了解决实际问题 - 雨夜

先看 思考和应用场景的问题 思考下,然后再继续往下看

如果可以的话 点个赞/评论下 哈哈 好有点动力 有问题 也请留言

2 背景

3 思考

本节就是要分阶段把 公平锁每个阶段 中redis的变化 图解画出来

这里不写细节 细节请看上一节

4 应用场景

5 公平锁图解

5.1 命名统一定义

a 第一个抢锁的线程 11:03:00 请求进来
b 第二个抢锁的线程 11:03:04 请求进来
c 第三个抢锁的线程 11:03:09 请求进来

5.2 a抢到锁了

hash 结构
lockKey f71f3609-1ec2-40dc-b31b-75aa4b0d7ab6:1 1

5.3 b进来抢锁 但是a已经占用着呢

lockKey锁的剩余时间pttl + tonumber(5000) + tonumber(当前时间);
26 + 5s + 当前时间11:03:04
11:03:35

image.png

5.4 c进来抢锁,但是a b已经占用了

ttl = 11:03:35 - 11:03:09 = 26s
ttl + tonumber(5000) + tonumber(当前时间);
26 + 5s + 11:03:09
11:03:40

image.png

5.5 a 在11:03:10 续约

image.png

5.6 a解锁 在11:03:14 解锁

"redis.call('publish', KEYS[4] .. ':' .. nextThreadId, ARGV[1]);

a解锁之后 publish 发送消息 通知b线程

image.png

5.7 先说一个少的情况 c先来尝试加锁 11:03:15

直接 timeout - tonumber(5000) - tonumber(当前时间); 11:03:40 - 5s - 11:03:15 20s 等20s之后 在调度

5.8 b来尝试加锁

hash 结构
lockKey f71f3609-1ec2-40dc-b31b-75aa4b0d7ab6:1 1
b加锁成功

image.png

5.9 如果a解锁 b没有续约 c之后来尝试加锁

b时间过期了,b被删除
c加锁成功,之后b进来,还在queue进行等待

8 总结:

这个就是公平锁 大概步骤的状态,有什么情况没写全 可以评论下

9 下节预知

  1. MultiLock 讲解

10 目标:

  1. 随着学习 把一些坑解决 形成一个 redission的基础组件

代码地址: gitee.com/gf-8/yuye-p…

项目: yuye-test-redission

类地址: 对应的test 包之下Test类

11 思考题