分布式锁解决方案

作者: 光剑书架上的书 | 来源:发表于2020-05-22 00:47 被阅读0次

    1. 基于数据库实现分布式锁

    在数据库中创建一个表,表中包含方法名等字段,并在方法名字段上创建唯一索引,想要执行某个方法,就使用这个方法名向表中插入数据,成功插入则获取锁,执行完成后删除对应的行数据释放锁。(性能不是特别高)

    创建一个表

    DROP TABLE IF EXISTS `method_lock`;
    CREATE TABLE `method_lock` (
      `id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键',
      `method_name` varchar(64) NOT NULL COMMENT '锁定的方法名',
      `desc` varchar(255) NOT NULL COMMENT '备注信息',
      `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (`id`),
      UNIQUE KEY `uidx_method_name` (`method_name`) USING BTREE
    ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COMMENT='锁定中的方法';
    

    想要执行某个方法,就使用这个方法名向表中插入数据。

    INSERT INTO method_lock (method_name, desc) VALUES ('methodName', '测试的methodName');
    

    由于对method_name做了唯一性约束,如果有多个请求同时提交到数据库,数据库会保证只有一个操作可以成功,那么就可以认为操作成功的那个线程获得了该方法的锁,可以执行方法体内容。

    成功插入则获取锁,执行完成后删除对应的行数据释放锁。

    delete from method_lock where method_name ='methodName';
    

    2. 基于Redis实现分布式锁

    获取锁的时候,使用setnx加锁,并使用expire命令为锁添加一个超时时间,超过该时间则自动释放锁,锁的value值可以为一个随机生成的UUID,通过此在释放锁的时候进行判断。
    获取锁的时候还设置一个获取的超时时间,若超过这个时间则放弃获取锁。
    释放锁的时候,通过UUID判断是不是该锁,若是该锁,则执行delete进行锁释放。
    setnx并不是原子操作,建议使用setex。另外基于Redission也可以实现分布式锁。

    3. 基于Zookeeper实现分布式锁

    基于ZooKeeper实现分布式锁的步骤如下:
    (1)创建一个目录mylock。
    (2)线程A想获取锁就在mylock目录下创建临时顺序节点。
    (3)获取mylock目录下所有的子节点,然后获取比自己小的兄弟节点,如果不存在,则说明当前线程顺序号最小,获得锁。
    (4)线程B获取所有节点,判断自己不是最小节点,设置监听比自己次小的节点。
    (5)线程A处理完,删除自己的节点,线程B监听到变更事件,判断自己是不是最小的节点,如果是则获得锁。

    4. 总结

    ZooKeeper版本的分布式锁问题相对比较来说少。

    锁的占用时间限制:redis就有占用时间限制,而ZooKeeper则没有,最主要的原因是Redis目前没有办法知道已经获取锁的客户端的状态,是已经挂了呢还是正在执行耗时较长的业务逻辑。而ZooKeeper通过临时节点就能清晰知道,如果临时节点存在说明还在执行业务逻辑,如果临时节点不存在说明已经执行完毕释放锁或者是挂了。由此看来redis如果能像ZooKeeper一样添加一些与客户端绑定的临时键,也是一大好事。

    是否单点故障:Redis本身有很多中玩法,如客户端一致性hash,服务器端sentinel方案或者cluster方案,很难做到一种分布式锁方式能应对所有这些方案。而ZooKeeper只有一种玩法,多台机器的节点数据是一致的,没有Redis的那么多的麻烦因素要考虑。


    Kotlin开发者社区

    专注分享 Java、 Kotlin、Spring/Spring Boot、MySQL、redis、neo4j、NoSQL、Android、JavaScript、React、Node、函数式编程、编程思想、"高可用,高性能,高实时"大型分布式系统架构设计主题。

    相关文章

      网友评论

        本文标题:分布式锁解决方案

        本文链接:https://www.haomeiwen.com/subject/cvcfahtx.html