zoukankan      html  css  js  c++  java
  • 分布式锁

    分布式锁

    • 借助数据库、Redis集群、Zookeeper集群作为辅助系统。

    • 面临的问题:

      1. 锁的一致性问题:在集群式辅助系统中,必然会存在锁的并发读,由于集群内部的数据同步存在延迟,不同客户端进程读到的锁可能不一致。

        • Zookeeper天生支持最终一致性,能在一定程度上满足。
        • Redison借助Redis集群借助redlock机制,也能保证最终一致性。
      2. 锁得不到释放:持有锁的进程崩溃,导致锁得不到释放,进一步导致其他进程被永久等待,称之为锁得不到释放。

        • 解决思路:给锁预设过期时间,一旦超超时锁会被强制释放,解决了永久等待问题。
      3. 锁的过早释放:新问题又产生了,预设的过期时间往往是一个经验值,可能出现持有锁的进程的正常逻辑还没执行完毕,锁就被错误的强制过期了,这时其他进程将会错误的执行,称之为锁的过早释放。

        • 简单粗暴,将超时时间设长一点,比如一分钟,这样能避免大部分的错误强制释放,但如果频繁发生进程故障,将导致大量的无效等待,优点是实现简单,不需要做额外开发,利用Redis的setIfAbsent+expire机制就可以实现。Redison就是基于此,同时在应用中开启后台线程定期给锁续约,避免锁的过早释放。
        • 给锁增加监听机制,一旦持有者崩溃就自动释放锁,将锁的释放权完全交给持有进程,这种方式合理高效,但实现复杂。

    1、数据库实现

    进程a先查询表,如果没有记录就向表中插入锁,拿到了锁,继续处理自己的逻辑;

    进程b也做同样的操作,查询发现表中已存在记录,表示锁被他人持有,进程b自旋查询等待;

    进程a处理完自己的逻辑后删除表中的记录。

    进程b查询表发现没有记录,将锁插入表,拿到了锁,继续处理自己的逻辑。

    2、Zookeeper实现

    每一个进程都到某个znode下创建一个临时有序子节点,同时每个进程都监听这个父znode。
    父znode下的每个子节点的变动都会触发进程重新拉取子节点列表,每个进程得到列表后比较自己的节点是否是列表中最小的那一个,如果是则表示得到了锁。执行完毕后断开连接,session失效对应的节点被删除,完成锁的释放。

    3、Redison实现

    借助setIfAbsent + expire + redlock + 后台续约线程。

  • 相关阅读:
    jQuery插件开发的模式和结构
    jQuery插件开发详细教程
    一个JavaScript Function Outliner插件 第三个版本 让你的JavaScript代码也支持折叠
    web开发过程中经常用到的一些公共方法及操作
    C#操作注册表
    EventBus使用详解(一)——初步使用EventBus
    android xml布局文件中tools:layout的作用
    调用android系统相机拍照并保存
    Android组件间通信库EventBus学习
    网络通信框架Volley使用详细说明
  • 原文地址:https://www.cnblogs.com/JaxYoun/p/12335222.html
Copyright © 2011-2022 走看看