Zookeeper是一个高性能的分布式协调中间件,所谓的分布式协调中间件的作用类似于分布式环境中各个服务进程的访问控制问题,比如访问顺序控制;

Zookeeper的数据结构

Zookeeper与Dubbo - 图1

Zookeeper的数据模型和分布式文件系统类似,是一种层次化的属性结构,如下图所示;和文件系统不同的是,Zookeeper的数据是结构化存储的,并没有在物理上体现出文件和目录;
zk树中的每个节点被称为Znode,Znode维护了一个stat状态信息,其中包含数据变化 的时间和版本,并且每个Znode可以设置一个value值,Zk并不用于通用的数据库或者大容量的对象存储,它只是管理和协调相关的数据,所以不建议value值过大,以免带来过大的网络开销;ZK上的每个节点是数据都是允许读写的;节点的创建规则病史是按照层级创建;

Zookeeper的特性

Zookeeper中的Znode的节点类型分为:

  • 持久化节点,节点的数据会被持久化到磁盘;
  • 临时节点,节点的生命周期和创建该节点的客户端的声明周期保持一致,一旦该客户端的会话结束,则该客户端所创建的临时节点会被自动删除
  • 有序节点,在创建节点后面会增加一个递增的序列,该序列在同一父节点之下是唯一的,需要注意的是持久化节点或者临时节点也可以被设置为有序节点在3.5.5版本后,又新增了两种节点类型,分别是:
  • 容器节点,当容器节点下的最后一个子节点被删除是,容器节点就会被自动删除
  • TTL节点,针对持久化及诶单或者持久化有序节点,我们可以设置一个存活时间,TTL节点就是设置存活时间的节点

Watcher机制

Zookeeper与Dubbo - 图2

zk提供了一而终针对Znode的订阅/通知机制;当Znode节点发生变化时或者Zk客户端链接状态发生变化时会触发时间通知;这个机制在服务注册与发现中,针对服务点用着及时感知服务提供者的的变化提供了非常好的解决方案;
Watcher事件的触发都是一次性的

master选举

Zookeeper与Dubbo - 图3

Zookeeper实现master选举的两种方式:

— 同一及诶单不能重复创建一个已经存在的节点,这个有点类似于分布式锁的实现场景,其实master选举的场景也是如此;假设集群中有3个节点,需要选举出master,那么这三个节点同事去Zookeeper服务器上创建一个临时节点/master-election,由于节点的特性,只会有一个客户端创建成功,创建成功的客户端所在的机器也就成了新的master
— 利用临时有序节点的特性来实现;所有参与选举的客户端在Zookeeper服务器的/master及诶单下创建一个临时有序及诶单,编号最小的节点表示master,后续的节点可以删除钱一个节点的删除时间,用于触发重新选举,如下图所示,client01,client02,client03三个及诶单去Zookeeper Server的master节点下创建临时有序节点,编号最小的client01表示Master节点,client02和client03分别会监听比自己编号小的一个节点;如client03 会监听client01-000000001节点的删除时间,client02监听client-03-0000002节点的删除事件,一旦最小的节点被删除,那么client03就会被选举为新的master

Zookeeper注册中心的实现原理

Dubbo服务注册到Zookeeper上之后,可以在Zookeeper服务器上看到如下所示的树形结构

Zookeeper与Dubbo - 图4
服务注册和动态感知的功能用到了Zookeeper中的临时节点,持久化节点,Watcher等;
— 基于临时节点的特性,当服务宕机或者下线时,注册中心会自动删除该服务提供者的信息;— 注册中心重启时,Dubbo能够自动回复注册数据及订阅请求
— 为了保证节点操作的安全性,zk提供了ACL权限控制,在Dubbo中可以通过dubbo.registry.username/dubbo.registry.password设置节点的验证信息;
— 注册中心的默认的根节点是/dubbo,如果需要针对不同环境设置不同的根节点,可以使用dubbo.registry.group修改根节点的名称

Dubbo集成Zookeeper

dubbo集成zk可以做到服务上下线感知,负载均衡等功能,dubbo支撑多种注册中心,比如zk,nacos,redis等,在开源版本中官方推荐的是zk;

Zookeeper与Dubbo - 图5
服务注册中心