zookeeper
概念
zookeeper 是一个开源的分布式框架 提供协调服务的apache项目
动物园用来管理hadoop 大象,hive 蜜蜂 pig 小猪
提供配置管理 分布式锁 集群管理
服务器特点
强一致性 ,有配置文件管理功能
- 一个leader 多个follower 集群
- 集群半数定理
- 全局一致性
- 请求按序,类似于公平锁
- 数据更新原子性
命令操作
数据模型
-
树形目录服务
-
Znode 每个节点都会保存自己的数据跟节点信息
-
节点可以拥有子节点,同时允许少量数据(1MB)存储在该节点之下。
-
节点可以分成四类:
- persistent持久化节点
- ephemeral临时节点 -e
- persistent_sequential持久化顺序节点 -s
- ephemeral_sequential临时顺序节点 -es
安装部署
1.docker安装zookeeper
集群搭建:https://www.cnblogs.com/kingkoo/p/8732448.html
https://blog.csdn.net/pushiqiang/article/details/78682323
zookeeper服务端集群搭建
- 下载
sudo pip install docker-compose
2.配置文件
version: '2'
services:
zoo1:
image: zookeeper:3.4.14
restart: always
container_name: zoo1
ports:
- "2181:2181"
environment:
ZOO_MY_ID: 1
ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
zoo2:
image: zookeeper:3.4.14
restart: always
container_name: zoo2
ports:
- "2182:2181"
environment:
ZOO_MY_ID: 2
ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
zoo3:
image: zookeeper:3.4.14
restart: always
container_name: zoo3
ports:
- "2183:2181"
environment:
ZOO_MY_ID: 3
ZOO_SERVERS: server.1=zoo1:2888:3888 server.2=zoo2:2888:3888 server.3=zoo3:2888:3888
zookeeper docker 客户端快速搭建
正常连接zookeeper服务端
./zkCli.sh -server ip:port
快速
---客户端
docker run -it --rm \
--link zoo1:zk1 \
--link zoo2:zk2 \
--link zoo3:zk3 \
--net zookeeper_default \ //这个--net 容器的networks查询
zookeeper:3.4.14 zkCli.sh -server zk1:2181,zk2:2181,zk3:2181
- 启动(在配置文件目录)
$ docker-compose up
# 若是要后台运行:
$ docker-compose up -d
# 若不使用默认的docker-compose.yml 文件名:
$ docker-compose -f server.yml up -d
通用
x1.端口说明
- 2171 :对client端提供服务
- 3888: 选举leader使用
- 2888:集群内机器通讯使用查看当前容器Networks
查看docker服务的network 用来link创建镜像
docker network ls
zookeeper状态查看
-
- 可以通过命令:echo stat|nc 127.0.0.1 2181 来查看哪个节点被选择作为follower或者leader
-
- 使用echo ruok|nc 127.0.0.1 2181 测试是否启动了该Server,若回复imok表示已经启动。
-
- echo dump| nc 127.0.0.1 2181 ,列出未经处理的会话和临时节点。
-
- echo kill | nc 127.0.0.1 2181 ,关掉server
-
- echo conf | nc 127.0.0.1 2181 ,输出相关服务配置的详细信息。
-
- echo cons | nc 127.0.0.1 2181 ,列出所有连接到服务器的客户端的完全的连接 / 会话的详细信息。
-
- echo envi |nc 127.0.0.1 2181 ,输出关于服务环境的详细信息(区别于 conf 命令)。
-
- echo reqs | nc 127.0.0.1 2181 ,列出未经处理的请求。
-
- echo wchs | nc 127.0.0.1 2181 ,列出服务器 watch 的详细信息。
-
- echo wchc | nc 127.0.0.1 2181 ,通过 session 列出服务器 watch 的详细信息,它的输出是一个与 watch 相关的会话的列表。
-
- echo wchp | nc 127.0.0.1 2181 ,通过路径列出服务器 watch 的详细信息。它输出一个与 session 相关的路径。
命令
进入子节点 ls /app
创建子节点 create /app1 数据
修改 set /app2 数据
删除 delete /app1
删除包括子目录 deleteall /app1
退出 quit
创建临时节点 会话断开就失效 create -e /appi
创建顺序节点 会自动给你加编号:create -s /appi --> 创建 /appi0000000001
查看节点信息 ls -s ls -s /app1
java 客户端操作zookeeper api
curator
Curator是Netflix公司开源的一套zookeeper客户端框架,解决了很多Zookeeper客户端非常底层的细节开发工作,包括连接重连、反复注册Watcher和NodeExistsException异常等等。Patrixck Hunt(Zookeeper)以一句“Guava is to Java that Curator to Zookeeper”给Curator予高度评价。
操作介绍:
https://www.jianshu.com/p/db65b64f38aa
创建连接
//1.第一种方式 集群用,隔开即可 192.168.128.129:2181,192.168.128.129:2181,192.168.128.129:2181,192.168.128.129:2181,
// RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
// CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.128.129:2181",
// 5000, 5000, retryPolicy);
// client.start();
//2.第二种方式
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.builder()
.sessionTimeoutMs(5000)
.connectString("192.168.128.129:2181")
.connectionTimeoutMs(5000)
.namespace("/dubbo/zxy")
.build();
client.start();
watch机制
Watcher机制是zookeeper最重要三大特性数据节点Znode+Watcher机制+ACL权限控制中的其中一个,它是zk很多应用场景的一个前提,比如集群管理、集群配置、发布/订阅
https://www.jianshu.com/p/4c071e963f18
watch监听的是某个节点或者某个节点树下的所有节点
引入watch机制来实现发布/订阅功能
三种watch 1.nodecache 单独节点的监听 2.pathchildrencache znode的子节点 3. treecache 相当于12的组合
java操作zookeeper watch
//1.创建NodeCache对象
NodeCache nodeCache = new NodeCache(client,"/app1");
//注册监听
nodecache.getListenable().addListener(new nodeCacheListener(){
overrider
public void nodeChanged() throws Exception{
System.out.printIn("节点变化了");
Byte[] data = nodeCache.getCurrenetData().getData();
System.out.printIn(new String(data));
}
})
//开启监听 如果为true 则开启监听时加载缓冲数据
nodeCache.start(true);
//pathChildrenCache 子节点的监听
//treecache 树节点监听
Zab协议内容
Zab 协议包括两种基本的模式:崩溃恢复 和 消息广播
协议过程
当整个集群启动过程中,或者当 Leader 服务器出现网络中弄断、崩溃退出或重启等异常时,Zab协议就会 进入崩溃恢复模式,选举产生新的Leader。
当选举产生了新的 Leader,同时集群中有过半的机器与该 Leader 服务器完成了状态同步(即数据同步)之后,Zab协议就会退出崩溃恢复模式,进入消息广播模式。
这时,如果有一台遵守Zab协议的服务器加入集群,因为此时集群中已经存在一个Leader服务器在广播消息,那么该新加入的服务器自动进入恢复模式:找到Leader服务器,并且完成数据同步。同步完成后,作为新的Follower一起参与到消息广播流程中。
协议状态切换
当Leader出现崩溃退出或者机器重启,亦或是集群中不存在超过半数的服务器与Leader保存正常通信,Zab就会再一次进入崩溃恢复,发起新一轮Leader选举并实现数据同步。同步完成后又会进入消息广播模式,接收事务请求。
保证消息有序
恢复模式的两个原则
当集群正在启动过程中,或 Leader 与超过半数的主机断连后,集群就进入了恢复模式。 对于要恢复的数据状态需要遵循两个原则。
1. 已被处理过的消息不能丢
当 Leader 收到超过半数 Follower 的 ACKs 后,就向各个 Follower 广播 COMMIT 消息, 批准各个 Server 执行该写操作事务。当各个 Server 在接收到 Leader 的 COMMIT 消息后就会在本地执行该写操作,然后会向客户端响应写操作成功。
但是如果在非全部 Follower 收到 COMMIT 消息之前 Leader 就挂了,这将导致一种后 果:部分 Server 已经执行了该事务,而部分 Server 尚未收到 COMMIT 消息,所以其并没有 执行该事务。当新的 Leader 被选举出,集群经过恢复模式后需要保证所有 Server 上都执行 了那些已经被部分 Server 执行过的事务。
2. 被丢弃的消息不能再现
当在 Leader 新事务已经通过,其已经将该事务更新到了本地,但所有 Follower 还都没 有收到 COMMIT 之前,Leader 宕机了(比前面叙述的宕机更早),此时,所有 Follower 根本 就不知道该 Proposal 的存在。当新的 Leader 选举出来,整个集群进入正常服务状态后,之 前挂了的 Leader 主机重新启动并注册成为了 Follower。若那个别人根本不知道的 Proposal 还保留在那个主机,那么其数据就会比其它主机多出了内容,导致整个系统状态的不一致。 所以,该 Proposa 应该被丢弃。类似这样应该被丢弃的事务,是不能再次出现在集群中的, 应该被清除。
在整个消息广播中,Leader会将每一个事务请求转换成对应的 proposal 来进行广播,并且在广播 事务Proposal 之前,Leader服务器会首先为这个事务Proposal分配一个全局单递增的唯一ID,称之为事务ID(即zxid),由于Zab协议需要保证每一个消息的严格的顺序关系,因此必须将每一个proposal按照其zxid的先后顺序进行排序和处理。
zookeeper的分布式锁(优秀)
实现原理 :当客户端要获取锁的时候,创建节点,使用完锁删除节点
- 客户端获取锁的时候,在某个Lock节点下创建临时顺序节点
- 然后或许lock下面的所有子节点,客户端获取倒所有的子节点,如果发现自己的子节点序号最小,那么认为改客户端获取到了锁,使用完了之后将该锁删除
- **(重点)**如果发现自己创建的节点并非Lock所有子节点中最小的,说明自己还没有获取到锁,此时客户端需要找到那个比自己小的顺序节点并对他注册时间监听器,监听删除事件。
- 如果发现比自己小的节点被删除,则客户端的watch接收到相对应的通知,此时再次判断自己创建的节点是否是lock子结点中最小的,如果是则获取到了锁,如果不是则重复3
curator实现分布式锁的api:(参考, 5种)
- 分布式排他锁,(非可重入锁)
- 分布式可重入排他锁 (同一个线程进入后需要多次释放锁)
- 分布式读写锁
- 将多个锁作为单个实体管理的容器
- 共享信号量
InterProcessMutex lock;
lock = new InterProcessMutex(client,path);
lock.acquire(3,TimeUnit.SECONDS);//设置客户端获取锁如果没获取到3秒后再试
记住会话结束 临时节点会删除。
zookeeper作为注册中心的缺陷
https://www.jianshu.com/p/d9fc146e7e9a