Redis分布式锁(附带思维导图)| 小册免费学

389 阅读2分钟

Redis分布式锁 (1).png

分布式锁是保存在一个共享存储系统中,可以被多个客户端共享访问和获取

而Redis恰好是一个共享存储系统

分布式锁和单机锁的联系

对于单机上运行的锁,其实就是一个变量【可以理解为信号量】

而分布式锁需要这个变量在共享存储系统中,因此

  • 分布式锁加锁和释放的过程中,需要保证操作的原子性(其实都需要保证)
  • 共享存储系统保存了锁变量,那么当共享存储系统坏了就很麻烦,因此需要保证该系统的可靠性

实现分布式锁

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

Redis使用键值对保存锁变量

加锁需要:1,读取锁,2,判断所变量是否为0,3,将锁变量置为1

如何保证原子性呢

Redis保证原子性有两种通用方法:

  • 使用Redis的单命令操作和Lua脚本

  • SETNX:如果name不存在,设置键值对的值,否则不操作

  • DEL删除锁(就算删除了变量,但下一次SETNX会自己建立)

因此可以使用上面两个命令实现加锁和释放锁

风险

在加锁后如果异常退出后就会让其他人无法加锁,建议增加一个过期时间

在A加锁后,如果B执行了释放锁,那A就被误释放了,这个时候C在加锁,就会同时有两个人加锁,因此需要区分不同的客户端,可以为每个不同的客户端设置不同的锁值,释放锁时只有两者相同才可以释放。

需要使用Lua脚本保证原子性

基于多个Redis 节点实现分布锁

多个Redis节点保证一个坏了也能用的高可靠

Redlock:客户端和多个独立的Redis实例依次请求加锁,如果客户端能够和半数以上的实例成功地完成加锁操作,则加锁成功,否则

  1. 客户端获取当前时间
  2. 客户端按顺序依次向N个Redis实例执行加锁操作
    • 单机加锁+设置加锁操作的超时时间(几十毫秒):如果超时前没有加锁成功,则跳过
  3. 计算加锁过程总耗时

加锁成功的判定

  • 超过半数拿到锁
  • 客户端获取锁的总耗时没有超过锁的有效时间

锁的有效时间为锁的最初有效时间 - 总耗时

文章末尾请带上以下文字及链接:本文正在参与「掘金小册免费学啦!」活动, 点击查看活动详情