对于Zookeeper的一些理解

简介: 该文档介绍了如何使用ZooKeeper实现统一配置、命名服务和分布式锁以及集群管理。首先,为了解决多个系统重复配置的问题,提出了抽取公共配置到`common.yml`并存储在ZooKeeper中的方法,系统通过监听ZNode变化实时更新配置。接着,详细说明了配置管理的实现步骤,包括在服务器端将配置同步到ZooKeeper,以及客户端监听配置变更。此外,还解释了命名服务如何根据名称获取服务地址,并以域名访问为例进行了说明。最后,讨论了ZooKeeper实现的两种分布式锁策略,并阐述了其在集群管理中的应用,如检测节点状态变化和选举Master节点。

实现统一配置

实现思路

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

实现方法

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

实现步骤

配置管理中心实现:

  1. 导入zkClient对应的jar。
  2. 实现工具类方法,完成从数据库加载配置、将配置文件保存到数据库、配置文件同步到zookeeper。
/**
   * 配置文件同步到zookeeper
   */
  public void syncConfigToZk(){
    ZkClient zk = new ZkClient("localhost:2181");
    if(!zk.exists("/zkConfig")){
      zk.createPersistent("/zkConfig",true);
    }
    zk.writeData("/zkConfig", config);
    zk.close();
  }
  1. 具体的代码是实现,将上面的1、2进行代码实现。运行就可以实现同步配置信息到zookeeper了,

客户端实现:

  1. 监听zookeeper中zkConfig对应的zoNode节点。
private Config config;
  public Config getConfig() {
    ZkClient zk = new ZkClient("localhost:2181");
    config = (Config)zk.readData("/zkConfig");
    System.out.println("加载到配置:"+config.toString());
    
    //监听配置文件修改
    zk.subscribeDataChanges("/zkConfig", new IZkDataListener(){
      @Override
      public void handleDataChange(String arg0, Object arg1)
          throws Exception {
        config = (Config) arg1;
        System.out.println("监听到配置文件被修改:"+config.toString());
      }
 
      @Override
      public void handleDataDeleted(String arg0) throws Exception {
        config = null;
        System.out.println("监听到配置文件被删除");
      }
      
    });
    return config;
  }

统一命名服务

命名服务功能主要是根据指定名字来获取资源或服务的地址、提供者信息,利用zookeeper我们可以创建唯一标识路径,这个路径可以作为一个名字,指定集群中的集群,提供的服务的地址或者一个远程对象。这个路径就好比是一个仓库,这个仓库的地址是唯一的,这些仓库里面存了一些东西,当我们来到这个仓库,我们就能取到仓库里的东西。

比如说,现在我有一个域名www.liancan.com,而这个域名下有多台机器:

192.168.0.91

192.168.0.93

192.168.0.94

192.168.0.95

通过访问 www.liancan.com 就可以访问到我的机器,而不是通过 IP 去访问,如下图所示:

分布式锁

实现分布式锁有两种,一种是保持独占,一种是控制时序。

  1. 第一种方式
  1. 我们将zookeeper上的节点看成一把锁,通过createznode的方式来实现,所有客户端都去创建/distribute_lock节点,最终成功创建的那个客户端就拥有了这把锁。用完删掉自己创建的节点就释放锁。
  2. 缺点:
  1. 注意:不适用于客户端数量很大的情况,当一个客户端拥有第一把锁之后,所有的客户端都要去监听节点,节点的释放也会通知所有的客户端,这样会出现羊群效应。
  1. 第二种方式
  1. 假设/distribute_lock已经预先存在,所有的客户端都在它下面创建临时顺序编号目录节点,编号最小的获取锁
  2. 没有获取到锁的客户端就监听编号比自己小的前一个节点,因为节点是有顺序的,很容易找到自己创建的前一个节点。
  3. 当监听到前一个节点删除节点,即释放锁,该客户端就会获得锁。
  4. 这样避免所有的客户端只需要监听一个节点和节点删除需要通知所有客户端的情况。
  5. 实现思路:
  1. 客户端 A 拿到 /distribute_lock 节点下的所有子节点,经过比较,发现自己(id_001),是所有子节点最小的。所以得到锁。
  2. 客户端 B 拿到 /distribute_lock 节点下的所有子节点,经过比较,发现自己(id_002),不是所有子节点最小的。所以监听比自己小的节点 id_001 的状态。
  3. 客户端 C 拿到 /distribute_lock 节点下的所有子节点,经过比较,发现自己(id_003),不是所有子节点最小的。所以监听比自己小的节点 id_002 的状态。
  4. 等到客户端 A 执行完操作以后,将自己创建的节点 id_001 删除。通过监听,客户端 B 发现 id_001 节点已经删除了,发现自己已经是最小的节点了,于是顺利拿到锁。

集群管理

在分布式环境中,掌握集群中每个节点的状态,zookeeper做集群管理可以实现检测是否有机器加入或退出,还可以用来选举集群的master。

只要客户端 A 挂了,那/GroupMember/A这个节点就会删除,通过监听 GroupMember 下的子节点,客户端 B 和客户端 C 就能够感知到客户端 A 已经挂了(新增也是同理)

相关文章
layui按条件开启关闭编辑列
layui按条件开启关闭编辑列
245 0
|
Java API 容器
JAVA并发编程系列(10)Condition条件队列-并发协作者
本文通过一线大厂面试真题,模拟消费者-生产者的场景,通过简洁的代码演示,帮助读者快速理解并复用。文章还详细解释了Condition与Object.wait()、notify()的区别,并探讨了Condition的核心原理及其实现机制。
|
8月前
|
缓存 人工智能 边缘计算
HTTP代理:网页加速的隐形引擎
本文深入探讨HTTP代理在提升网页加载速度中的核心作用与技术原理。通过请求中转、协议优化及传输层加速,结合智能缓存、动态压缩、全球负载均衡和协议升级四大黑科技,实现显著性能提升。同时分析其潜在代价与挑战,并展望边缘计算、AI驱动等未来趋势,为选型提供实用指南。
382 10
|
存储 SQL Java
Spring Boot使用slf4j进行日志记录
本节课主要对 slf4j 做了一个简单的介绍,并且对 Spring Boot 中如何使用 slf4j 输出日志做了详细的说明,着重分析了 logback.xml 文件中对日志相关信息的配置,包括日志的不同级别...
|
人工智能 监控 5G
5G 网络切片的动态管理:实现灵活高效的网络资源分配
5G 网络切片的动态管理:实现灵活高效的网络资源分配
720 1
|
机器学习/深度学习 算法 数据挖掘
从菜鸟到大师:Scikit-learn库实战教程,模型训练、评估、选择一网打尽!
【9月更文挑战第13天】在数据科学与机器学习领域,Scikit-learn是不可或缺的工具。本文通过问答形式,指导初学者从零开始使用Scikit-learn进行模型训练、评估与选择。首先介绍了如何安装库、预处理数据并训练模型;接着展示了如何利用多种评估指标确保模型性能;最后通过GridSearchCV演示了系统化的参数调优方法。通过这些实战技巧,帮助读者逐步成长为熟练的数据科学家。
495 3
|
Java 开发者 Spring
Java一分钟之-Java网络编程基础:Socket通信
【5月更文挑战第13天】本文介绍了Java Socket编程基础知识,包括使用`ServerSocket`和`Socket`类建立连接,通过`OutputStream`和`InputStream`进行数据传输。常见问题涉及忘记关闭Socket导致的资源泄漏、网络异常处理及并发同步。理解Socket通信原理并掌握异常处理、资源管理和并发控制,能帮助开发者构建更稳定的网络应用。
375 1
|
存储 SQL 关系型数据库
【MySQL技术内幕】6.1-锁、lock和latch
【MySQL技术内幕】6.1-锁、lock和latch
339 0
|
算法 数据可视化 C#
C# | Chaikin算法 —— 计算折线对应的平滑曲线坐标点
本文将介绍一种计算折线对应的平滑曲线坐标点的算法。该算法使用Chaikin曲线平滑处理的方法,通过控制张力因子和迭代次数来调整曲线的平滑程度和精度。通过对原始点集合进行切割和插值操作,得到平滑的曲线坐标点集合。实验结果表明,该算法能够有效地平滑折线,并且具有较高的精度和可控性。
701 0
C# | Chaikin算法 —— 计算折线对应的平滑曲线坐标点
|
图形学 C++
Qt实现Qchart的打印和打印预览的几种方法
Qt实现Qchart的打印和打印预览的几种方法

热门文章

最新文章