SpringBoot结合ZooKeeper实现分布式锁

本文介绍了ZooKeeper,一个中心化的服务,用于协调分布式进程,提供数据存储、命名服务和集群服务。重点讲解了其数据模型、ZAB协议、数据操作以及如何使用Curator库实现分布式锁。
摘要由CSDN通过智能技术生成

ZooKeeper 介绍


ZooKeeper 一个中心化的服务, 用于维护配置信息, 命名服务(naming), 提供分布式同步和集群服务(group services)。
它是一个开源的分布式应用程序协调服务, 作为 Google Chubby的一个开源实现, 是Hadoop和Hbase的重要组件。 ZooKeeper 的目标是封装好复杂易出错的关键服务, 暴露简单易用、高效、稳定的接口给用户使用, 提供基于java和C的接口。

Zookeeper 的核心实现是一个分布式的数据存储系统,其内部采用 ZAB 协议(Zookeeper Atomic Broadcast)进行主从复制,确保了数据的一致性和可靠性。在 Zookeeper 中,数据存储采用了一种称为“Znode”的数据模型,类似于 Unix 文件系统。
Znode 是 Zookeeper 中最基本的数据单元,是一个有层级的树形结构,每个节点都有一个路径,其中根节点为“/”,子节点路径会在父节点路径的基础上加上相对路径,最终形成一棵完整的树形结构。


Zookeeper的设计目标


简单
ZooKeeper 允许分布式的进程之间通过一个共享的层级命名空间(hierarchinal namespace, 和文件系统类似)进行协调。
ZK 实现了高性能、高可用和严格顺序访问, 是的它可以用于大规模分布式系统, 无单点故障问题, 和复杂的同步原语。
ZK 提供了简单的编程接口。

复制的(replicated)
ZooKeeper和其它的分布式进程一样, 也是一个集群的主机作为一个整体。

有序(ordered)
ZooKeeper用一个数字表示每一次的更新, 以反映所有 ZooKeeper 事务的顺序。后续可以利用这个顺序来实现诸如同步原语之类的高级抽象。

快速(fast)
ZooKeeper在读多写少的负载中性能尤其高, 读写比例大概处于 10:1 时表现最好。


Zookeeper的数据模型


Zookeeper使用一种树状数据模型来表示数据结构。每个节点在这个树状结构中都有一个唯一的路径,这个路径由节点的绝对路径组成。绝对路径是一个以斜杠(/)开头的字符串,表示从根节点到当前节点的路径。
Zookeeper的数据模型包括以下几个组成部分:

节点:节点是Zookeeper中的基本数据结构,它可以存储数据和元数据。
路径:路径是节点的唯一标识,用于表示节点在树状结构中的位置。
父节点:每个节点都有一个父节点,表示它在树状结构中的父节点。
子节点:每个节点都可以有多个子节点,表示它在树状结构中的子节点。

Zookeeper的数据操作


Zookeeper提供了一系列的数据操作接口,用于对数据进行CRUD操作。这些操作接口包括:
create:创建一个新节点。
get:获取一个节点的数据。
set:设置一个节点的数据。
delete:删除一个节点。
exists:检查一个节点是否存在。
sync:同步一个节点的数据。


Zookeeper实现分布式锁


分布式锁主要用于在分布式环境中保护跨进程、跨主机、跨网络的共享资源实现互斥访问,以达到保证数据的一致性。Zookeeper实现分布式锁是通过持久节点和临时顺序节点来完成的,实现思路如下:

获取锁:


1. 首先我们要有一个持久节点/locks,客户端获取锁就是在locks下创建临时顺序节点。
2. 假设客户端 1 创建了/locks/lock1节点,创建成功之后,会判断 lock1是否是 /locks 下最小的子节点。
3. 如果 lock1是最小的子节点,则获取锁成功。否则,获取锁失败。
4. 如果获取锁失败,则说明有其他的客户端已经成功获取锁。客户端 1 并不会不停地循环去尝试加锁,而是在前一个节点比如/locks/lock0上注册一个事件监听器。这个监听器的作用是当前一个节点释放锁之后通知客户端 1(避免无效自旋),这样客户端 1 就加锁成功了。

释放锁:


1. 成功获取锁的客户端在执行完业务流程之后,会将对应的子节点删除。
2. 成功获取锁的客户端在出现故障之后,对应的子节点由于是临时顺序节点,也会被自动删除,避免了锁无法被释放。
3. 我们前面说的事件监听器其实监听的就是这个子节点删除事件,子节点删除就意味着锁被释放。


 Curator


 实际项目中,推荐使用 Curator 来实现 ZooKeeper 分布式锁。Curator 是 Netflix 公司开源的一套 ZooKeeper Java 客户端框架,相比于 ZooKeeper 自带的客户端 zookeeper 来说,Curator的封装更加完善,各种API都可以比较方便地使用。Curator主要实现了下面四种锁:
 InterProcessMutex:分布式可重入排它锁
 InterProcessSemaphoreMutex:分布式不可重入排它锁
 InterProcessReadWriteLock:分布式读写锁
 InterProcessMultiLock:将多个锁作为单个实体管理的容器,获取锁的时候获取所有锁,释放锁也会释放所有锁资源(忽略释放失败的锁)。

 以下是使用Curator的部分代码示例
 在项目的pom.xml中引入Curator依赖
 

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>5.6.0</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>5.6.0</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-client</artifactId>
    <version>5.6.0</version>
</dependency>

业务代码测试:

public String createOrderCurator(Integer productId, Integer count) throws Exception {
    InterProcessMutex lock = new InterProcessMutex(curatorFramework, "/lockPath");
    //try to get lock.
    if(lock.acquire(5,TimeUnit.SECONDS)) {
        try {
            //todo 模拟业务操作
            Thread.sleep(2000);
            return "create order finished!";
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            lock.release(); 
        }
    }
    return "error to create lock!";
}

福利来了,京东618无门槛红包,速抢,亲测可用!!!

京东618狂欢红包,无门槛,速抢!!!icon-default.png?t=N7T8https://u.jd.com/kbEMRtj

  • 29
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

u010303355

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值