ZooKeeper简介及代码示例

ZooKeeper是一个开源的分布式协调服务,主要服务于分布式系统,可以用ZooKeeper来做:统一配置管理、统一命名服务、分布式锁、集群管理。使用分布式系统就无法避免对节点管理的问题(需要实时感知节点的状态、对节点进行统一管理等等),而由于这些问题处理起来可能相对麻烦和提高了系统的复杂性,ZooKeeper作为一个中间件就应运而生。
ZooKeeper的数据结构,可以看做是一颗树,每个节点叫做ZNode。每一个节点可以通过路径来标识,Znode分为两种类型:

短暂/临时(Ephemeral):当客户端和服务端断开连接后,所创建的Znode(节点)会自动删除
持久(Persistent):当客户端和服务端断开连接后,所创建的Znode(节点)不会删除

ZooKeeper和Redis一样,也是C/S结构(分成客户端和服务端)

ZooKeeper还配合了监听器。常见的监听场景有以下两项:

  1. 监听Znode节点的数据变化
  2. 监听子节点的增减变化

统一配置管理

	比如我们现在有三个系统A B C,他们分别有三份配置,然后这三份配置又非常类似,很多配置项几乎都一样
此时,如果我们要改变其中一份配置项的信息,很可能另外两份都要修改,改变了配置项的信息很可能就要重启系统
于是,我们希望将三份配置文件中,相同的配置项抽取出来一份公共的配置文件Common.yml,并且即便改了common.yml文件,也不需要重启A  B C 系统 

Zookeeper的做法:我们可以将Common.yml这份配置放在Zookeeper的Znode节点中,系统A B C监听着这个Znode节点有无变更,如果变更了,及时响应

统一命名服务

统一命名服务可以理解为域名,是我们为某一部分资源取得一个名字,别人可以根据这个名字拿到对应的资源

比如,我们现在有一个域名叫 www.java.com,但是我们这个域名下面有多台机器:
192.168.1.1、192.168.1.2、192.168.1.3、192.168.1.4
别人通过访问 www.java.com 即可访问到我的机器,而不是通过ip访问

分布式锁

节点被访问的时候会创建 带顺序号的临时节点,接着拿到该节点下的所有子节点,判断自己创建的是不是最小那个节点。
如果是,这是拿到了锁。执行完操作后,把创建的节点删除掉,并释放锁
如果不是,则监听比自己小1的节点变化

集群状态

只要A系统挂掉,那么对应的临时节点,也就会删除,其他的系统通过监听父节点下的子节点,就能感知A系统挂掉了
除了感知节点的上下线变化,Zookeeper还可以实现动态的选举Master的功能(如果集群是主从架构的模式下)

原理也很简单,如果想实现动态选举master的功能,Znode节点的类型是带顺序好的临时节点就好了
Zookeeper 会每次选举最小编号的作为master,如果master挂掉了,自然对应的Znode节点就会被删除,然后让最小编号作为master,这样就能实现动态选举的功能了

下面是在Java项目中使用ZooKeeper的一些实际代码示例:

  1. 引入依赖

在maven项目的pom.xml中加入以下依赖:

<!--ZooKeeper client依赖-->
<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.6.3</version>
</dependency>
  1. 创建连接和节点
String connectString = "localhost:2181"; // ZooKeeper的地址,多个地址用逗号分隔
int sessionTimeout = 3000; // 会话超时时间
Watcher watcher = watchedEvent -> {
    if (watchedEvent.getState() == Watcher.Event.KeeperState.SyncConnected) {
        System.out.println("ZooKeeper session established.");
    }
};
ZooKeeper zk = new ZooKeeper(connectString, sessionTimeout, watcher); // 创建连接
String nodePath = "/myNode"; // 节点路径
String data = "This is a test."; // 节点数据
CreateMode createMode = CreateMode.PERSISTENT; // 节点类型,这里为持久化节点
zk.create(nodePath, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, createMode); // 创建节点
  1. 读取节点数据
String nodePath = "/myNode"; // 节点路径
Stat stat = zk.exists(nodePath, false); // 获取节点状态,第二个参数表示是否使用watcher
if (stat != null) { // 如果节点存在
    byte[] dataBytes = zk.getData(nodePath, false, null); // 获取节点数据,第二个参数表示是否使用watcher
    String data = new String(dataBytes);
    System.out.println("Node data: " + data);
}
  1. 更新节点数据
String nodePath = "/myNode"; // 节点路径
String newData = "This is a new test."; // 更新后的数据
Stat stat = zk.exists(nodePath, false);
if (stat != null) {
    zk.setData(nodePath, newData.getBytes(), stat.getVersion()); // 更新节点数据,并指定版本号
}
  1. 删除节点
String nodePath = "/myNode"; // 节点路径
Stat stat = zk.exists(nodePath, false);
if (stat != null) {
    zk.delete(nodePath, stat.getVersion()); // 删除节点,并指定版本号
}

以上是ZooKeeper在Java项目中的一些实际代码示例,其中还包括一些高级用法,如监听器、ACL权限控制等。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值