zookeeper基本使用和分布式锁

zookeeper和分布式锁

介绍:
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

zookeeper常用命令

●Is/ls2 path
列出当前目录下的全部子目录,|s2会多包含-一些状态信息
●create path data
创建持久Znode,并存放数据data
●create -e path data
创建临时Znode,并存放数据data
●create- s-e path data
在Znode下创建临时顺序节点
●get path
获取Znode存储的数据
●set path data [version]
给Znode赋值
●delete path [version]
删除Znode

特殊命令

●stat path watch
注册监听Znode,如果Znode删除、 创建通知注: Znode可以是一个不存在的节点
●get path watch
注册监听Znode保存的数据变化
●Is path watch
注册监听Znode下的子节点变化,包括新增和删除

结果集注释

cZxid .
创建节点时的事务ID
ctime
创建节点时的时间
mZxid
最后修改节点时的事务ID
mtime
最后修改节点时的时间
pZxid
表示该节点的子节点列表最后- -次修改的事务ID,添加子节点或删除子节点就会影响子节点列表,但是
修改子节点的数据内容则不影响该ID
cversion
子节点版本号,子节点每次修改版本号加1
dataversion
数据版本号,数据每次修改该版本号加1
aclversion
权限版本号,权限每次修改该版本号加1
dataL ength
该节点的数据长度
numChildren
该节点拥有子节点的数量

zookeeper 集群配置

  1. 把Zookeeper准备好
  2. 进入conf目录,拷贝z00_ sample.cfg zo0.cfg
  3. vim zoo.cfg
  4. tickTime: zookeeper的时间单位单位ms
  5. initLimit:允许follower连接并同步到L eader的初始化连接时间
  6. syncLimit:允许L eader与Follower之间发送消息和应答时间限制
  7. dataDir:存储Zookeeper数据和日志路径
  8. clientPort:客户端连接服务器端口

示例
在这里插入图片描述
9. server .A=B:C:D
A:其中A是一个数字,表示这个是服务器的id
B:是这个服务器的ip地址
C: Leader选举的端口
D: Zookeeper服务器之间的通信端口
10. 创建myid文件 每个zookeeper的myid和server 配置的对等

示例
在这里插入图片描述
11. 分别启动zookeeper服务器 ./zkServer .sh start
12. zkServer.sh status查看当前服务器是哪个角色
13. 登录不同的zookeeper服务器./zkCli.sh [server:prot]

zookeeper java常用api

maven坐标

<dependency>
            <groupId>com.101tec</groupId>
            <artifactId>zkclient</artifactId>
            <version>0.11</version>
</dependency>

public ZkClient(String serverstring)
public ZkClient(String serverstring,int connectionTimeout)
public ZkClient(String serverstring,int sessionTimeout,int connectionTimeout)
public ZkClient(String serverstring,int sessionTimeout,int connectionTimeout,ZkSerializer zkSerializer)
public ZkClient(lZkConnection connection)
public ZkClient(IZkConnection connection,int connectionTimeout)
public ZkClient(IZkConnection connection,int connectionTimeout,ZkSerializer zkSerializer)
serverstring可以指定单个服务器地址也可以是多个,zookeeperlP:port,zookeeperlP:port.
connectionTimeout, sessionTimeout 是连接超时时间和会话超时时间。单位都是毫秒,会话默认是30000毫秒。

创建znode
String create(path,data,CreateMode)
创建持久znode
createPersistent(path,data)
创建临时znode
createEphemeral(path,data)
创建临时顺序znode
String createEphemeralSequential(path,data)
创建持久顺序znode
String createPersistentSequential(path,data)
    
    
删除znode
boolean delete(path)
判断znode是否存在
boolean exists(path)
获取znode全部子节点
List<String> getChildren(path)
给znode设置值
writeData(path,data)
读取znode保存的数据
readData(path)

    
    
注册znode及znode数据监听
void subscribeDataChanges(path, IZkDataListener)
注册znode子节点监听
Void subscribeChildChanges(path, IZkDataL jistener)

分布式锁

基于上面的api基础上实现一个简单的分布式锁,我这里用简单的适配器模式编写,可按照需求改进
ZookeeperLock.java

package com.xm93cc.zookeeperdistributedlock.lock;/*
*******
QDebug
*******
*******
2020/7/14 21:32
*******
*/

public interface ZookeeperLock {
    public void lock();
    public void unlock();
}

AbstractZookeeperLock.java

package com.xm93cc.zookeeperdistributedlock.lock;/*
*******
QDebug
*******
*******
2020/7/14 21:30
*******
*/

import org.I0Itec.zkclient.ZkClient;

import java.util.concurrent.CountDownLatch;

public abstract class AbstractZookeeperLock implements ZookeeperLock {

    protected String ipAddr ="127.0.0.1:2181";

    protected ZkClient zkClient=new ZkClient(ipAddr);

    protected String lock="/";

    protected CountDownLatch countDownLatch;

    /**
     * 加锁
     */
    @Override
    public void lock() {
      if(tryLock())
          System.out.println("拿到锁");
      else {
          waitLock();
          lock();
      }
    }

    /**
     * 卸载锁
     */
    @Override
    public void unlock() {
        if (zkClient!=null)
            zkClient.close();
        else
            System.out.println("not lock ....");

    }

    protected abstract void waitLock();
    protected abstract boolean tryLock();
}

ZookeeperLockAchieve.java

package com.xm93cc.zookeeperdistributedlock.lock;/*
*******
QDebug
*******
*******
2020/7/15 14:16
*******
*/


import org.I0Itec.zkclient.IZkDataListener;

import java.util.concurrent.CountDownLatch;

public class ZookeeperLockAchieve extends AbstractZookeeperLock {

    public ZookeeperLockAchieve(String lock) {
        super.lock = lock;
    }

    /**
     * 等待锁
     */
    @Override
    protected void waitLock() {
        IZkDataListener iZkDataListener = new IZkDataListener() {
            @Override
            public void handleDataChange(String s, Object o) throws Exception {

            }

            @Override
            public void handleDataDeleted(String s) throws Exception {
                if (countDownLatch != null)
                    countDownLatch.countDown();
            }
        };
        zkClient.subscribeDataChanges(lock, iZkDataListener);

        if (zkClient.exists(lock)) {
            countDownLatch = new CountDownLatch(1);
            try {
                countDownLatch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        zkClient.unsubscribeDataChanges(lock, iZkDataListener);


    }

    /**
     * 尝试锁
     * @return
     */
    @Override
    protected boolean tryLock() {
        try {
            zkClient.createEphemeral(lock);
            return true;
        } catch (Exception e) {
            return false;
        }

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值