浅谈分布式锁-Zookeeper

基于zookeeper 实现分布式锁

上篇文章讲到了redis实现分布式锁的方法,也对分布式锁中锁产生的不一致性的的问题简单的讲解。这篇也简单说下zk实现分布式锁。

实现原理

临时节点

让多个进程一同去创建临时节点,这些进程必然只会有一个去创建临时节点,创建临时节段的进程就会抢占到这个锁。同时如果释放锁,就去删除这个znode。如果这是时候客户端宕机了,或者挂了,zk的watch机制也会检测到与客户端没有通信。也会删除这个临时znode,这时候其他的进程监测这个znode,一旦发生这种情况,会有其他的线程继续创建临时znode。

这种机制有效避免了客户端与zk发生死锁的情况,但是也会大大增加服务端压力,一个临时节点的释放,会有多个线程监听并抢占一个锁,这就是zk分布式锁的羊群效应,如何有效避免这种情况。并且这种锁不是公平锁,就会发生有的线程会一直抢不到锁。这时候就要进行有序的临时节点

有序的临时节点

1.每个进程都会去临时节点下创建锁,这时候创建的是有序的递增临时节点。比如znode000000000001,第二个创建的就是znode000000000002。
2.这时候会获取都所有节点的的值,判断自己是不是最小值。
3.如果是最小值,则通过watch高速客户端获取了这把锁。

这个有序锁解决了公平锁的问题,但是没有解决羊群效应所带来的zk的瞬间的压力

读写锁

读写锁用的也是用的有序的临时节点。
这时候读写算不用去取关注自己是不是最小节点。只需要关注自己的前一个节点有没有释放,如果钱一个节点释放了,就获取了这把锁。

读写锁有效的解决了公平锁的问题和羊群效应

Apache Curator

Apache Curator 是 ZooKeeper 的 Java 客户端,它基于临时有序节点方案实现了分布式锁、分布式读写锁等功能

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>4.3.0</version>
</dependency>
<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>4.3.0</version>
</dependency>
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.14</version>
</dependency>

基本使用:

RetryPolicy retryPolicy = new RetryNTimes(3, 5000);
CuratorFramework client = CuratorFrameworkFactory.builder()
    .connectString("192.168.0.105:2181")
    .sessionTimeoutMs(10000).retryPolicy(retryPolicy)
    .namespace("mySpace").build();
client.start();

// 1. 创建分布式锁
InterProcessMutex lock = new InterProcessMutex(client, "/distributed/myLock");
// 2.尝试获取分布式锁
if (lock.acquire(10, TimeUnit.SECONDS)) {
    try {
        System.out.println("模拟业务耗时");
        Thread.sleep(3 * 1000);
    } finally {
        // 3.释放锁
        lock.release();
    }
}
client.close();

这时候如果有多个线程来获取这把锁,那么指定路径下会创建多个有序的锁。

关于源码我就不多做介绍了

脑裂

众所周知,zookeeper集群的所有操作都是Leader操作的,如果一个集群内有多个leader的话,就会导致整个集群的数据不一致的情况。破坏了整个集群的可用性。

zk解决这个问题依靠选票机制,奇数节点和半个以上的票数的支持。这样就保证了一个集群内只有一个leader。

也就是说一个集群内至少有三个节点,且存活的节点要>2.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值