zookeeper介绍

zookeeper介绍

zookeeper

  • Zookeeper是一个分布式协调服务。
  • 分布式应用程序可以基于zookeeper实现同步服务,配置维护和命名服务等。
  • zookeeper可以保证数据在zookeeper集群之间的数据的事务性一致。

zookeeper的特点

  • 数据一致性:为客户端展示同一视图
  • 可靠性:如果消息被一台服务器接受,那么它将被所有服务器接受
  • 原子性:更新只能成功或失败,没有中间状态。

zookeeper架构

zookeeper架构

zookeeper的角色

  • 领导者(leader),负责进行投票的发起和决议,更新系统状态
  • 学习者(learner),包括跟随者(follower)和观察者(observer),follower用于接受客户端请求并向客户端返回结果,在选主过程中参与投票。observer可以接受客户端连接,将写请求转发给leader,但observer不参加投票过程,只同步leader的状态,observer的目的是为了扩展系统,提高读取速度。
  • 客户端(client):请求发起方

zookeeper命令行

  • 常用命令
    • 查看节点下面信息 ls /
    • 创建节点 create /test data
    • 获取节点上保存的数据 get /test
    • 修改节点数据 set /test databak
    • 递归删除节点 rmr /test
    • 使用delete命令删除节点,但是节点下面不能有子节点

zookeeper的数据模型

  • 层次化的目录结构,命名符合常规文件系统规范。
  • 每个节点在zookeeper中叫做znode,并且其有一个唯一的路径标识。
  • 节点znode可以包含数据和子节点,但是ephemeral(临时节点)类型的节点不能有子节点
  • znode中的数据可以有多个版本,比如某一个路径下存有多个数据版本,那么查询这个路径下的数据就需要带上版本。
  • 客户端应用可以在节点上设置监视器。
  • 节点不支持部分读写,而是一次性完整读写。

zookeeper的节点

  • znode的两种类型,临时节点(ephemeral)和永久节点(persistent)
  • znode的类型在创建时确定并且之后不能再更改
  • 临时znode的客户端会话结束时,zookeeper会将该临时znode删除,临时znode不可以有子节点。
  • 永久znode不依赖于客户端会话,只有当客户端明确要删除该node时,才会被删除。
  • znode有四种形式的目录节点,persistent、persistent_sequential、ephemeral、ephemeral_sequential.

^(* ̄(oo) ̄)^: znode可以是临时节点,一旦创建这个znode的客户端与服务器失去联系,这个znode也将自动删除,zookeeper的客户端和服务器通信采用长连接方式,每个客户端和服务器通过心跳来保持连接,这个连接状态成为session,如果znode是临时节点,这个session失效,znode也就删除了,持久化目录节点这个目录节点存储的数据不会丢失。

zookeeper实现分布式监控

  • 假设要监控多台服务器上的A程序运行状态,当发现有服务器上的A程序下线的时候,给管理员发短信,并尝试重启A程序

  • 主要利用zk的临时节点和watcher监视器特性

    1. 首先在A程序启动的时候在zookeeper的/monitor节点下创建一个临时节点的名称,可以用这个服务器的主机名或者ip信息,只要A程序一直正常运行,这个临时节点就会一直存在。
    2. 给zk的/monitor节点注册一个watcher监视器,监视monitor节点下面的所有子节点的变化情况,当有子节点变化的时候,获取到具体是哪个子节点发生了变化,就知道哪台机器上的A程序有问题了。
    3. 可以给管理员发短信,打电话,发邮件之类的,并且还可以实现对那一台服务器上的A程序进行重启。

    zookeeper实现分布式共享锁

  • 首先假设有两个线程,两个线程要同时到mysql中更新一条数据,对数据库中的数据进行累加更新。由于在分布式环境下,这两个线程可能存在于不同的机器上的不同jvm进程中,所以这两个线程的关系就是垮主机跨进程,使用java中的synchronized锁是搞不定的

  • 主要利用了zookeeper的临时有序节点特性和watcher监视器。

    • 我们认为最小的节点具备执行权,也就是获取到了锁。
    • 大致思路
      • 1:当这两个线程去mysql更新数据之前,先到zookeeper的/locks(永久节点)下面注册一个临时有序节点,这样每个线程都注册了一个临时节点,两个临时节点肯定是有序的。
      • 线程1:/locks/000 000 000 2 线程2:/locks/000 000 000 1
      • 当每个线程注册完节点之后,需要尝试获取锁,这个时候,哪个节点最小,哪个节点就获取到锁,这个时候。线程2注册的节点最小,所以线程2就获取到锁,执行更新数据库的代码,更新完成之后,删除自己注册的临时节点。
      • 同时线程1会判断自己是不是最小的,所以会监控比自己小1的那个节点,当发现那个节点消失的话,也就意味着它的节点就是最小的节点,获取锁,执行更新数据的代码。。。

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×