Zookeeper

Zookeeper是一个开源的分布式(多台服务器干一件事)的,为分布式应用提供协调服务的Apache项目。

  • Zookeeper从设计模式角度来理解:是一个基于观察者模式(一个人干活,有人盯着他)设计的分布式服务管理框架。

  • 它负责 存储 和 管理 大家都关心的数据

    • 然后接受观察者的注册,一旦这些数据的发生变化
    • Zookeeper就将负责通知已经注册的那些观察者做出相应的反应
    • 从而实现集群中类似Master/Slave管理模式
  • Zookeeper = 文件系统 + 通知机制

分布式和集群的区别?

无论分布式和集群,都是很多人在做事情。
具体区别如下:

  • 例如:我有一个饭店,越来越火爆,我得多招聘一些工作人员
    • 分布式:招聘1个厨师,1个服务员,1个前台,三个人负责的工作不一样,但是最终目的都是为饭店工作
    • 集群:招聘3个服务员,3个人的工作一样

集群概念

  1. 是一个leader和多个follower来组成的集群(狮群中,一头雄狮,N头母狮)
  2. 集群中只要有半数以上的节点存活,Zookeeper就能正常工作(5台服务器挂2台,没问题;4台服
    务器挂2台,就停止)
  3. 全局数据一致性,每台服务器都保存一份相同的数据副本,无论client连接哪台server,数据都是
    一致的
  4. 数据更新原子性,一次数据要么成功,要么失败
  5. 实时性,在一定时间范围内,client能读取到最新数据
  6. 更新的请求按照顺序执行,会按照发送过来的顺序,逐一执行(发来123,执行123,而不是321
    或者别的)

存储结构

  • 每个节点默认可以存储1MB的数据,只能存储string类型数据
  • 节点类型
    • 持久型
      • 持久化目录节点
      • 持久化顺序编号目录节点:zk自动编号
    • 临时型(连接断开后会消失)
      • 临时目录节点
      • 临时顺序目录节点

zookeeper应用场景

  • 统一命名服务
  • 统一配置管理
  • 服务器节点上下线通知
  • 软负载均衡

zookeeper内部原理

  • 选举机制
    • 集群中半数以上机器存活,集群可用。
    • zk内部会自动产生一个leader,其余都是slaver
  • 节点类型
  • 监听器原理
  1. 在main方法中创建Zookeeper客户端的同时就会创建两个线程,一个负责网络连接通信,一个负责监听
  2. 监听事件就会通过网络通信发送给zookeeper
  3. zookeeper获得注册的监听事件后,立刻将监听事件添加到监听列表里
  4. zookeeper监听到 数据变化 或 路径变化,就会将这个消息发送给监听线程
  5. 监听线程就会在内部调用process方法(需要我们实现process方法内容)
  • 写数据的过程


  1. Client 想向 ZooKeeper 的 Server1上写数据,必须的先发送一个写的请求
  2. 如果Server1不是Leader,那么Server1会把接收到的请求进一步转发给Leader
  3. 这个Leader会将写请求广播给各个Server,各个Server写成功后就会通知Leader
  4. 当Leader收到半数以上的 Server数据写成功了,那么就说明数据写成功
  5. 随后,Leader会告诉Server1数据写成功
  6. Server1会反馈通知 Client 数据写成功了,整个流程结束

分布式锁

zookeeper内部提供了一个分布式锁,但是调用很麻烦,我们通过Apache提供的封装方法来实现zk分布式锁。

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-recipes</artifactId>
    <version>4.2.0</version>
</dependency>
// 重试策略 (1000毫秒试1次,最多试3次)
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
//1.创建curator工具对象
CuratorFramework client = CuratorFrameworkFactory.newClient(zookeeperConnectionString, retryPolicy);
client.start();
//2.根据工具对象创建“内部互斥锁”
InterProcessMutex lock = new InterProcessMutex(client, lockPath);
try {
    //3.加锁 
    lock.acquire(); 
    productService.reduceStock(id); 
}catch(Exception e){ 
    if(e instanceof RuntimeException){ 
    throw e; 
    } 
}finally{ 
    //4.释放锁 
    lock.release(); 
}

疑问
在CuratorFrameworkFactory.newClient()提供zookeeper的地址的时候如果是采用集群来搭建的ZK是需要提供多个ZK地址吗

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容