zookeeper
什么是zookeeper?
分布式一致性协调服务框架
换言之,也可以zookeeper看成一个小型的分布式文件系统,
但是与FastDFS不同,zookeeper只适合用来存储一些小型的数据或者配置信息
提供配置信息管理,命名服务,分布式同步
zookeeper安装
1.zookeeper是纯java的所以需要JDK环境
2.单机安装-配置data/log路径后启动即可
zookeeper的文件系统
文件系统的数据结构
zookeeper底层是一个树形结构,用来存储数据
和Linux,Window等系统不同,Linux和Window中有文件和文件夹的概念,文件夹下面才能有文件,文件下面不能有文件,文件夹本身不存放数据,文件本身用来进行数据存储;
zookeeper中的结点,没有文件夹和文件之分,所有结点都可以进行数据存储,同时也可以拥有子节点;
每个结点称之为ZNode
ZNode的分类
1.临时节点-ephemeral:
临时节点由某个客户端创建,如果该客户端断开了和zookeeper服务器的连接,则该临时节点就会自动删除;
注意:临时节点不能有子节点
2.持久性节点-persistent:
持久化的节点会永久存在于文件系统中,除非客户端显示的删除该节点;该节点是最常见的节点;
3.顺序节点:
3.1临时顺序节点-ephemeral_sequential:
和临时节点有相同的特点,唯一的区别在于该节点名称会自动维护一个编号
3.2持久顺序节点-persistent_sequential:
和持久化的节点由相同的特点,唯一的区别在于该节点名称会自动维护一个编码
zookeeper文件系统操作命令
1…/zkCli.sh ip -p port;
进入命令行
2.ls path;
查看某个路径下的子节点情况,在zookeeper中只能写绝对路径,所有的路径都必须从/出发
3.create -s(顺序节点) -e(临时节点) path(路径) data(数据) acl(权限);
创建新节点,数据不能为空
4.get path;
查看指定路径对应的节点数据(数据部分+描述部分)
5.set path data [version]
修改指定节点的数据
6.delete path data
删除指定节点的数据
Java如何操作zookeeper
引入依赖然后,创建 zookeeper对象操作即可
zookeeper的通知(watch)机制
什么是通知机制?
客户端可以选择对某个ZNode进行监听,当这个ZNode发生变化时(本身的添加删除,修改以及子ZNode的变化),会主动通知监听了这个ZNode的客户端,zookeeper的通知机制有一次性触发原则,ZNode发生变化后,一旦通知了客户端,则断开客户端的监听,如果需要继续监听节点的变化,则必须重新发起监听
监听方法
自定义类MyWatch实现Wathcer接口,实现zookeeper的通知回调方法
//判断abc是否存在,并设置一个监听
//可以监听到节点创建,节点的内容修改,节点的删除
//但是不能监听到子节点的变化
zookeeper.exists("/abc",new MyWatch());
//无法监听到节点的创建,如果abc不存在则报错
//可以监听当前节点的内容修改,删除
zookeeper.getData("/abc",new MyWatch(),null);
//无法监听到节点的创建,如果abc不存在则报错
//无法监听节点本身的变化
//可以监听子节点的变化,子节点的添加和删除
//但是不包含内容变化,也不包括孙子节点的变化
zookeeper.getChildren("/abc",new MyWatch());
watch类型
1.数据watch
exists();
getData();
2.孩子watch
getChildren();
注意:不同的API监听的动作不同
事件类型
None:断开连接
NodeCreated:t添加
NodeDeleted:删除
NodeDataChanged:只和版本号有关
NodeChildrenChanged:子节点创建或删除
ZooKeeper的运用场景(重点)
1.配置文件统一管理
对分布式系统来说,有很多服务部署在不同的服务器上,不同的服务器有自己一套配置,如果需要配置进行调整,则需要对多台服务器逐个的修改,是不便于管理的
在zookeeper中创建/Configuration持久化节点,将配置信息放在其中
每个客户端都监听(Watch机制)该持久节点,如果有新的配置信息,开发者只需要上传到zookeeper这个节点上(更新节点的配置数据),一旦节点内容修改,每个应用都会得到zookeeper的通知,然后从中获得新的配置信息,在系统中完成配置更新;
2.集群管理
所谓集群管理无在乎两点:是否有机器退出和加入,选举master
在某些集群中可能需要其他集群服务器的状态,比如有机器加入或退出集群等,这个时候就可以通过zookeeper进行集群的统一管理
所有机器约定在父目录/GroupMembers下创建临时节点,每一个节点就代表一台机器,然后监听父目录节点的子节点的变化消息
一旦有机器添加和删除,每个机器都会收到通知,接受通知后,每个机器可以在查询节点信息,就可以知道哪个节点添加或者删除,就知道哪个机器进入或退出了,然后进行集群的配置
master选举的话我们一般通过在父节点创建顺序临时节点,选择编号最小的机器即可
3.分布式锁
实现方式:
1.保持独占:单进程
我们把zookeeper上的一个znode看做一把锁,所有的客户端同时创建一个lock临时节点,通过createNode()方法,谁创建成功,谁就获得锁了;业务操作结束后,释放锁删除该节点即可,就算客户端断开临时节点也会删除所以不用担心会形成死锁;
2.控制时序:加锁排队
创建一个父节点,所有的客户端在它下面创建顺序临时节点,我们保证编号最小的获得这个锁就可以了
4.命名服务(服务的发现和注册)
Dubbo使用的就是这个场景,基于ZooKeeper注册中心,命名服务
假设有一个A服务需要调用B服务,但是AB是两个互相独立的服务,A先完成,B还没有完成
A就可以主动获得zookeeper某个节点"/name",A就可以不需要再管了,B一旦完成,B直接去"/name"节点上将地址加入其中,A服务就监听到了节点内容的修改,就能够调用该地址
对于集群的负载均衡在父节点下面添加子节点就可以实现
Dubbo+ZooKeeper
在zookeeper的根目录下有/dubbo节点
/dubbo节点下面就是我们发布的服务节点
各个服务节点下面就有我们的服务信息,消费者,提供者,配置信息各种节点…
服务者节点中就存放了我们需要的调用地址,消费者一旦启动就会去其中获得调用地址,并且消费者也有地址但没有实际作用;
ZooKeeper集群,leader-follower
ZooKeeper集群由N台机器搭建,这些机器中一定会存在一个leader,其他的机器都是follower,所有客户端都可以随意连接集群中的任一机器;
对于内容修改操作,所有的follower都会收到leader的命令,由leader发起投票,票数超过一半以上则提交命令
集群搭建两种方式
伪集群模式
单机机器中启动多个ZooKeeper进程,并组成集群
步骤:
1.将单机装的zookeeper文件复制两份
2.在zookeeper/data中创建myid文件并编写id编码
3.修改zookeeper/conf/zoo.cfg核心配置文件port,以及data/log路径,还要配置
server.1=127.0.0.1:2888:3888
server.2=127.0.0.2:2889:3889
server.3=127.0.0.3:2890:3890
(这两个端口是集群内部通讯的端口)
真实集群就是不需要修改配置port和data路径
然后配置server的时候ip不一致
4.启动集群
./zkServer.sh status 查看服务状态,可知道leader/follower角色
集群模式
过半数存活原则
在zookeeper集群中,当存活的机器数量超过总机器的一半的时候,整个集群才能正常工作,否则拒绝访问
基于过半数存活原则,zookeeper的集群机器数量一定是奇数台,因为2N+1和2N+2的容灾能力是一样的,基于成本考虑2N+1台的选择方案更优
为什么zookeeper需要设计一个过半数存活机制?
为了防止网络脑裂,保证数据的强一致性
因为整个集群中,有可能因为网络问题"脑裂",导致整个集群分为2个甚至多个集群,如果没有过半数存活机制,那么整个zookeeper会变成多个集群,那么zookeeper提供的数据无法再保证数据一致性;
zookeeper集群角色
1.Leader领导者
2.Learner学习者:
Follower跟随者:
ObServer观察者:功能和追随者一致,响应客户端的命令,不能参加选举和投票环节
3.Client客户端
ZAB协议-原子消息广播协议
ZooKeeper作为高可用的一致性协调框架
自然的ZooKeeper也有着一致性算法的实现,ZooKeeper使用的是ZAB协议作为数据一致性的算法,ZAB(ZooKeeper Atomic Broadcast )
ZAB基础
Leader选举;
在ZooKeeper中所有的事务请求都由一个主服务器也就是Leader来处理,其他服务器为Follower,Leader将客户端的事务请求转换为事务Proposal,并且将Proposal分发给集群中其他所有的Follower,然后Leader等待Follwer反馈,当有过半数(>=N/2+1)的Follower反馈信息后,Leader将再次向集群内Follower广播Commit信息,Commit为将之前的Proposal提交;
ZAB协议的状态
Looking:选举状态
Leading:领导状态
Following:跟随状态
zookeeper配置详解
核心配置文件zoo.cfg
tickTime:心跳间隔时间,默认为2000ms
zookeeper中使用的基本时间单位, 毫秒值。
dataDir:数据目录。
修改为zookeeper安装目录下的data目录,data目录自己创建,当然也可以指定为别的目录。
initLimit:连接超时时间
Follower初始化连接时和Leader连接的超时时间。默认为10(10 * 2000ms(tickTime))
zookeeper集群中的包含多台server,其中一台为leader,其余的server为follower。
initLimit参数配置初始化连接时,follower和leader之间的最长心跳时间。
syncLimit:消息通信超时时间
该参数配置leader和follower之间发送消息,请求和应答的最大时间长度。
此时该参数设置为2,说明时间限制为2倍tickTime,即4000ms
集群配置详解
server.serverid=serverhost:leader_listent_port:quorum_port
serverid:myid
是当前zookeeper服务器的id(myid文件中写的编号)。
leader_listen_port:领导监听端口
通常叫做原子广播端口,是该服务器一旦成为leader之后需要监听的端口,用于接收来自follower的请求。
quorum_port:选举端口
通常叫做选举端口,是集群中的每一个服务器在最开始选举leader时监听的端口,用于服务器互相之间通信选举leader。