• java 分布式锁


    公司项目有一个功能需要用到分布式锁功能,一开始使用redis(redisson)实现分布式锁,后来比较以后使用zookeeper(spring-integration-zookeeper),这边做下总结:

    分布式的 CAP 理论告诉我们:任何一个分布式系统都无法同时满足一致性(Consistency)、可用性(Availability)和分区容错性(Partition tolerance),最多只能同时满足两项。

    基于 CAP理论,很多系统在设计之初就要对这三者做出取舍。

    目前常见的三种分布式锁:

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

    a 乐观锁:基于表主键唯一做分布式锁

    b 悲观锁:基于数据库排他锁做分布式锁,for update,InnoDB 引擎在加锁的时候,只有通过索引进行检索的时候才会使用行级锁,否则会使用表级锁。mysql数据库的默认引擎(5.1版本之后)是InnoDB,所以这块要多注意

    2 基于缓存的分布式锁

    基于 redis的 setnx()、expire() 方法做分布式锁:

      setnx:SET if Not Exists,其主要有两个参数 setnx(key, value)。该方法是原子的,如果 key 不存在,则设置当前 key 成功,返回 1;如果当前 key 已经存在,则设置当前 key 失败,返回 0

      expire:设置过期时间,要注意的是 setnx 命令不能设置 key 的超时时间,只能通过 expire() 来对 key 设置

    基于 REDISSON 做分布式锁:redisson 是 redis 官方的分布式锁组件,里面有封装好的api

    3 基于Zookeeper实现的分布式锁

    ZooKeeper是一个为分布式应用提供一致性服务的开源组件,它内部是一个分层的文件系统目录树结构,规定同一个目录下只能有一个唯一文件名:

      a 基于开源库Curator,它是一个ZooKeeper客户端,Curator提供的InterProcessMutex是分布式锁的实现,acquire方法用于获取锁,release方法用于释放锁

      b 基于spring-integration-zookeeper

    几种方案的比较

    从理解的难易程度角度(从低到高)

    数据库 > 缓存 > Zookeeper

    从实现的复杂性角度(从低到高)

    Zookeeper > 缓存 > 数据库

    从性能角度(从高到低)

    缓存 > Zookeeper >= 数据库

    从可靠性角度(从高到低)

    Zookeeper > 缓存 > 数据库

    4 还有一种基于 Consul 做分布式锁:

    出自程序员DD https://blog.didispace.com/spring-cloud-consul-lock-and-semphore/

    基于Consul的分布式锁主要利用Key/Value存储API中的acquire和release操作来实现。acquire和release操作是类似Check-And-Set的操作:

    • acquire操作只有当锁不存在持有者时才会返回true,并且set设置的Value值,同时执行操作的session会持有对该Key的锁,否则就返回false
    • release操作则是使用指定的session来释放某个Key的锁,如果指定的session无效,那么会返回false,否则就会set设置Value值,并返回true

    具体实现中主要使用了这几个Key/Value的API:

     项目组综合比较之后倾向于使用Spring Integration 优雅的实现分布式锁,最终使用spring-integration-zookeeper

    Spring Integration在基于Spring的应用程序中实现轻量级消息传递,并支持通过声明适配器与外部系统集成。 Spring Integration的主要目标是提供一个简单的模型来构建企业集成解决方案,同时保持关注点的分离,这对于生成可维护,可测试的代码至关重要。我们熟知的 Spring Cloud Stream的底层就是Spring Integration。

    Spring Integration提供的全局锁目前为如下存储提供了实现:

    • Gemfire
    • JDBC
    • Redis
    • Zookeeper
  • 相关阅读:
    flash 异性窗体
    ASCⅡ 表 关键字符
    VC 中显示位图的步骤
    输出电脑的所有Mac地址
    const char* 和 char* const
    C# 生成PDF
    vc6显示行号
    纪念一下。
    MII接口全家福
    Virtex6 GTX设计总结:预加重、均衡、输出振幅的值
  • 原文地址:https://www.cnblogs.com/hzzjj/p/14727441.html
Copyright © 2020-2023  润新知