Redis 分布式锁简单解析

概念

分布式锁就是分布式场景下的锁,比如多台不同机器上的进程,去竞争同一项资源,就是分布式锁。

优秀分布式锁的特征

  • 互斥性: 只能有一个竞争者持有锁
  • 安全性: 避免死锁发生, 所以需要设置过期时间, 防止意外崩溃无法释放锁
  • 对称性: 同一个锁, 加锁者必须负责解锁, 也就是加锁和解锁必须是同一个任务, 不能解除其他任务的锁
  • 可靠性: 需要具有一定程度的异常处理和抗压, 容灾能力

分布式锁的实现方式

最简单版本(互斥性)

setnx key value

如果 key 不存在, 则会 将 key 设置为 value, 返回 1

如果 key 存在, 则不会有影响(不会加锁), 返回 0

delete key

通过 delete 解锁

image-20220525203828913

支持过期时间(互斥性, 安全性)

  • 使用 redis 中的 expire(失效) 命令, 设置一个 key 的锁的过期时间
  • 由于 setnx 和 expire 不是原子操作, 所以 redis 又有原子操作的语句
set key value nx ex seconds
// set a 1 nx ex 3

加上 owner (互斥性, 安全性, 对称性)

  • 服务A获取了锁,由于业务流程比较长,或者网络延迟、GC卡顿等原因,导致锁过期,而业务还会继续进行。这时候,业务B已经拿到了锁,准备去执行,这个时候服务A恢复过来并做完了业务,就会释放锁,而B却还在继续执行
  • 真实场景中, 会有更多的服务, 也就是出现这种情况会更加多
  • 所以规定: 分布式锁需要满足谁申请谁释放原则,不能释放别人的锁,也就是说,分布式锁,是要有归属的。

使用 Lua (检查和删除的原子性)

  • 执行完毕后,检查锁,再释放,这些操作不是原子化的。
  • Redis + Lua,可以说是专门为解决原子问题而生
image-20220525204020972

可靠性如何保证

容灾考虑

主从容灾

  • 配置从节点, 当主节点挂掉的时候使用从节点来接替主节点
  • 主从切换本来需要人工成本, 但 redis 通过哨兵模式可以自动切换
  • 但是增加从节点也会因为同步时延, 从节点 slave 可能会丢失部分部分数据, 这样分布式锁就失效了

多机部署

  • 比如说 redis 的 Redlock 技术, 需要一半以上的分布式机器(一般是奇数个)接受到加锁才算加锁成功
  • 加锁过程
  1. 向 5 个 Redis 加锁
  2. 如果有超过 3 个 Redis 返回成功, 那么就是获取到了锁, 如果失败, 则需要重新发送请求
  3. 由于向 5 个 Redis 发送请求,会有一定时耗,所以锁剩余持有时间,需要减去请求时间。这个可以作为判断依据,如果剩余时间已经为 0 ,那么也是获取锁失败
  4. 使用完之后, 再向 5 个 Redis 发送解锁请求
  • 单点 Redis 的所有手段,这种多机模式都可以使用,比如为每个节点配置哨兵模式,由于加锁是一半以上同意就成功,那么如果单个节点进行了主从切换,单个节点数据的丢失,就不会让锁失效了。这样增强了可靠性。

可靠性深究

  • 由于分布式锁中的 NPC 问题, 所以没有完全可靠的 分布式锁

Network Delay(网络延迟)

可能因为网络延迟返回的加锁请求时延过长, 但 RedLock 使用 锁剩余持有时间 – 请求时间, 可以一定程度上减缓网络延迟问题

Process Pause(进程暂停)

比如发生 GC, 获取锁之后 GC , GC 结束之后 锁也过期了, 此时两个业务都请求该锁

image-20220525204304001

因为无法判断 GC 何时结束, 所以不好去判断该锁的归属者.

Clock Drift(时钟漂移)

如果竞争者A,获得了 RedLock ,在5台分布式机器上都加上锁。为了方便分析,我们直接假设5台机器都发生了时钟漂移,锁瞬间过期了。这时候竞争者B拿到了锁,此时A和B拿到了相同的执行权限

参考

  • 小林coding
  • Redis 设计与实现
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇