redis实现分布式锁


redis实现分布式锁

  • redis的setNx和setEx实现分布式锁

    • 原理:setNx同时只有一个能设置成功值,其他线程来改动值都不会成功,因此只有一个线程能拿到锁lock,执行完成后删除lock即可。

    • 实现方式:

      1. 先拿分布式锁。

      2. 拿锁设置过期时间。(避免死锁)

      3. 执行业务成功,删除拿到锁。

      4. 没拿到锁,执行递归操作只到拿到锁为止。(阻塞)

    • 存在问题:

      • 问题1:第1步和第2步设置过期时间不连贯(因为redis是单线程,可能其他线程执行redis命令,例如keys * 卡死后会进行等待),不能保证原子性,因此redis提供了两条命令同时封装的函数(set key value ex 10 nx),合并为一条执行。
      • 问题2:设置锁过期时间为5s,但是业务执行了10s,此时锁已删除,业务还在执行(业务时间大于锁时间),其他线程同时又能拿到锁,但是第一个线程执行完可能又会删除第二个线程的锁。
        • 因此可以通过value来判断是否为自己加的锁,匹配值进行解锁(例如key产品id,value为uuid)。
        • 可以给锁一直加时间,单独定时任务去处理加时间(守护线程)设置最大容忍时间。=>redisson的诞生
  • redisson实现分布式架构(中小公司够用)

    • 配置:
      • 引入相关pom依赖。(在已有redis依赖的基础上引入)
      • @Bean注入相关config。
    • 实现方式:
      • 实现lock后能拿到锁的会一直尝试加锁,知道加锁成功为止(阻塞)(自旋锁)
      • 每隔10s去检查锁是否过期,如果持有锁,则继续延长锁时间30s(避免死锁)
    • 存在问题:(小概率)
      • 如果redisson一直将锁写在redis主节点,然后还未同步给从节点,突然主节点挂了,redis内部会重新选举产生新的主节点。此时未同步的从节点变为了主节点,其他线程过来仍能拿到锁。
    • 实现原理图
      • 1

文章作者: zhaolin.long
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 zhaolin.long !
 上一篇
Markdown语法 Markdown语法
1. 标题 # 这是标题1 ## 这是标题1 ###### 这是标题6 2. 有序列表 在行首增加 1.、2.、3.,即数字和英文句点, 注意句点与文字中间有空格。不要求数字一定要连续 3. 无序列表 在行首增加 * 或 - 与
2020-03-11
下一篇 
Maven详解 Maven详解
Maven详解 定义: 依赖管理:maven工程对jar包管理。 项目构建:编译、测试、打包、安装、发布整个工程交给maven管理。 寻址路径:pom.xml–>本地仓库–>(私服[公司内部])–>中央仓库 (本地仓
2020-03-11
  目录