Redis分布式锁原理

150 阅读2分钟

读写锁

顾名思义,就是分为读锁跟写锁,读锁共享写锁互斥,其核心思想为:

  • 读读共享
  • 读写互斥
  • 写写互斥

锁结构

存储为hash 为了区分读锁还是写锁,所以还需要一个key来标识当前锁是是读锁还是写锁

  1. mode:read/write
  2. uuid:threadId:1 唯一标识:重入次数
  3. timeout:3000 过期时间

读锁加锁

特点读读共享

  • 第一次读锁进入:
    • mode:read
    • uuid:threadId:1
    • timeout:3000
  • 第二次读锁进入:
    • 判断是自己的锁则重入次数+1,刷新过期时间
      • mode:read
      • uuid:threadId:2
      • uuid:threadId:timeout:3000
    • 不是自己的锁则:
      • mode:read
      • uuid:threadId:1
      • uuid:threadId:timeout:3000
      • uuid:threadId2:1
      • uuid:threadId2:timeout:3000

写锁加锁

特点读写互斥,写写互斥

  • 第一次写锁进入
    • mode:write
    • uuid:threadId:1
    • timeout:3000
  • 第二次写锁进入
    • 判断是自己的锁则重入次数+1,刷新过期时间
      • mode:write
      • uuid:threadId:2
    • 判断不是自己的锁
      • 加锁失败
  • 加了写锁后,后面进来只要不是自己的锁统统加锁失败

锁释放

  • 释放时,不能直接删除key,更不能直接删除整个hash,要考虑重入和非重入

读锁释放

  • 重入
    • 重入次数-1
  • 非重入
    • 删除key和自己的timeout
    • 判断hash除了mode外是否还有别的线程,如果没有直接删除这个hash

写锁释放

  • 重入
    • 重入次数-1
  • 非重入
    • 因为写锁没有timeout,所以直接删除整个hash就可以

watchDog

就像上面例子中的,续期时间的设置主要是两方面

  1. 整个hash的有效时间
  2. hash中key的有效时间(写锁只有自己,所以没有timeout) 重入的时候刷新hash和对应key的有效时间。
  • 写锁互斥,所以只需要给整个hash设置有效时间就可以了
  • 读读共享,所以不进要设置整个hash的有效时间,同时也要设置每个线程的有效时间