• Redis分布式锁原理


    转自:

    https://www.cnblogs.com/sky-chen/p/11362935.html

    1. Redis分布式锁原理

    1.1. Redisson

    现在最流行的redis分布式锁就是Redisson了,来看看它的底层原理就了解redis是如何使用分布式锁的了

    1

    1.2. 原理分析

    分布式锁要解决的是分布式环境下,并行相同代码的加锁功能;了解过redis分布式锁的人肯定知道,一开始redis作为分布式锁用的是setnx,再这基础上设置个定时过期时间,但这种方式有什么问题呢?

    实际上看懂上图的人也就明白了那有什么问题,首先是原子性问题,setnx+过期时间这两个操作必须是原子性的,所以这可以用lua脚本解决

    再然后是释放锁的时机该如何定?

    • 不管我们定多少过期时间,都不能保证,在这段时间内锁住的代码执行完成了,所以这个时间定多少都不好;
    • 如果不定时间,当执行完成后释放锁,问题就是如果执行到一半机器宕机,那这把锁就永远放不掉了

    那Redisson是如何解决上述问题的呢?

    • 它对代码进行了精简的封装,我们的使用非常简单,甚至我们不用主动设置过期时间
    • 它设计了个watch dog看门狗,每隔10秒会检查一下是否还持有锁,若持有锁,就给他更新过期时间30秒;通过这样的设计,可以让他在没有释放锁之前一直持有锁,哪怕宕机了,也能自动释放锁
    • 而不能获得锁的客户端则是不断循环尝试加锁
    • 通过记录锁的客户端id,可以把它设计成可重入锁
      1

    1.3. 存在问题

    redis作为分布式锁再大多数情况下是没问题的,但是我们知道CAP原理,一致性,可用性,分区容错性

    在redis分布式架构中,我们其实保证的是AP模型,也就是尽可能的保证了redis的可用性,这在一般系统中当然是没问题的,哪怕有时候一致性有点问题(实际读到的数据不正确,或已经写入没读到)毕竟是作为缓存的存在,一定延迟可以接受,没读到可以再读数据库,这是没问题的。

    但在分布式锁中,一旦出现该读到没读到,那就是重复锁的问题了,相当于分布式锁没起到作用。

    这种情况发生在什么时候呢?redis集群主节点再获取锁后,没来得及复制数据给从节点,此时宕机了,从节点接替主节点进行读写,此时新的主节点没有持有该锁,那么其他想要获取该锁的服务也可以获取到该锁,导致了重复锁的问题。

    一般来讲这种情况发生的概率是很小的,看你系统的规模而定,我觉得像阿里这种规模就应该不会用redis来作为分布式锁了

    CP模型的分布式锁可以用zookeeper,可能性能略低于redis,但能保证安全,可以提供顺序锁等额外功能

    参考:面试请不要再问我Redis分布式锁的实现原理!

  • 相关阅读:
    gradle使用笔记
    MaxScale初探
    mariadb-10GTID复制及多源复制
    Shell中的循环语句实例
    Failed to load slave replication state from table mysql.gtid_slave_pos: 1146: Table 'mysql.gtid_slave_pos' doesn't exist
    学习MongoDB--(5-2):索引(查看索引的使用,管理索引)
    MongoDB索引管理
    mysql 5.5与5.6 timestamp 字段 DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP的区别
    MongoDB增加用户、删除用户、修改用户读写权限及只读权限(注:转载于http://www.2cto.com/database/201203/125025.html)
    MongoDB创建数据库
  • 原文地址:https://www.cnblogs.com/heyanan/p/12800061.html
Copyright © 2020-2023  润新知