一、入门
1. 概述
Zookeeper是一个开源的分布式的,为分布式应用提供协调服务的程序。
- 基于观察者模式的分布式服务管理框架:文件系统+通知机制
- 负责存储和管理关心的数据,然后接受观察者的注册,一旦数据发生变化就会通知注册的观察者。
(1)服务端启动时去Zookeeper注册信息 (2)客户端通过Zookeeper获取到当前在线服务器列表,并且监听 (3)当服务器有节点下线时,Zookeeper通知客户端下线事件 (4)客户端重新再去获取Zookeeper获取列表,并注册监听
2. 特点
(1)Zookeeper集群中,多个节点拥有一个Leader和多个Follower (2)集群中只要有半数以上节点存活,Zookeeper集群就能正常服务 (3)集群中每个Server节点数据一致,Client连接哪个Server都一样 (4)更新请求顺序进行,来自同一个Client的更新请求暗器发送顺序依次执行 (5)数据更新具有原子性,要么一次更新全成功,要么就失败 (6)实时性,由于Zookeeper维护的数据很少,所以效率很高,Client能读到最新数据。
3. 数据结构
Zookeeper数据模型的结构与Unix文件系统很类似,整体上可以看作一棵树, 每个节点称作一个ZNode
- 每个ZNode默认能够存储1MB数据。
- ZNode存储的数据并非文件,而是直接是字符串
4. 应用场景
统一命名服务:在分布式环境下,经常需要对应用/服务进行统一命名,便于识别。如多个分布式服务器IP不同,但统一命名为同一个域名网址 统一配置管理:一个集群中,所有节点配置信息基本是一致的,因此要求对配置文件修改后,由Zookeeper管理配置可以快速同步到各个节点上。 统一集群管理:Zookeeper可以通过监听ZNode,来获取节点的实时状态变化 服务器节点动态上下线 软负载均衡:在Zookeeper中记录每台服务器的访问数,让访问数最少的服务器去处理最新的客户端请求,实现负载均衡。
二、应用
启动/关闭Zookeeper
- 启动关闭Zookeeper服务器:运行zkServer.sh脚本
bin/zkServer.sh start
bin/zkServer.sh stop
bin/zkServer.sh status
- 启动关闭Zookeeper客户端: 运行zkCli.sh
bin/zkCli.sh -server hadoop102:2181
bin/zkCli.sh
三、内部原理
1. 监听器原理
@Before
public void init() throws IOException {
connectString = "hadoop102:2181,hadoop103:2181,hadoop104:2181";
int sessionTimeout = 10000;
zkClient = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
@Override
public void process(WatchedEvent event) {
}
});
}
public void lsAndWatch() throws KeeperException, InterruptedException {
List<String> children = zkClient.getChildren("/atguigu", new Watcher() {
@Override
public void process(WatchedEvent event) {
System.out.println(event);
}
});
}
- main()线程创建Zookeeper客户端,此时就会产生两个线程:负责网络连接通信的connect和负责监听的listener
- connect线程通过匿名内部类的方式将注册的监听事件发送给Zookeeper
- 在Zookeeper的注册监听器列表中将注册的监听事件添加到列表中
- Zookeeper监听到有数据或路径变化,就会将高消息发送给listener线程
- listener线程内部调用了process()方法
2. 选举机制
当Zookeeper第一次启动时
- server1 启动,首先server1给自己投一票,然后看当前票数是否超过半数,结果没有超过,这时候leader就没选出来,当前选举状态是Locking状态。
- server2 启动,首先server2先给自己投一票,因为当前集群已经有两台机器已启动,所以server1、server2会交换选票,交换后发现各自有一票,接下来比较myid 发现server2的myid值 > server2的myid值,此时server2胜出,最后server2有两票。最后再看当前票数是否半,发现未过半,集群的选举状态, 集训保持locking状态。
- server3启动, 首先自己投自己一票,server1和server2也会投自己一票,然后交换选票发现都一样,接着比较myid 最后server3胜出,此时server3就有3票,同时server3的票数超过半数。所以server3成为leader。
- server4和server启动,都发现当前集群已经有leader,自己自动成为follower
当Zookeeper已经在使用中并已存在数据
- 当已存在的leader宕机时,集群会重新选出一个leader,此时首先会比较每一台机器的czxid,因为czxid越大代表其操作的时间约靠后,说明其数据更加完整
- czxid最大的被选为leader。极端情况,czxid都相等的情况,那么就会直接比较myid。
3. 写数据流程
- 客户端向ZK集群中的一台机器server1发送写数据的请求
- server1收到请求后马上会通知leader有些数据的请求
- laader拿到请求后进行广播,让集群每一台机器都准备要写数据
- 集群中的所有机器接收到leader广播后都会回应leader
- leader再次进行广播开始写数据,其他机器收到广播后开始写数据
- 数据写入成功后回应leader,最后由leader来做整个事物的提交
- 当数据成功写入后,由最初和客户端发生连接的server1回应客户端数据写入成功。
|