zookeeper总结
zookeeper的特点
zookeeper是一个分布式文件系统,适合存放小文件,也可以理解为一个数据库,在zookeeper中存储的是Znode,其是有路径的。
所有zookeeper的节点具有文件的增删改查功能。
zookeeper的应用场景
数据订阅和发布
利用watch机制,让用户可以随时获取动态信息。
命名服务
分布式系统中,被命名的实体通常可 以是集群中的机器、提供的服务地址或远程对象等,通过命名服务,客户端可以根据指定名 字来获取资源的实体,在分布式环境中,上层应用仅仅需要一个全局唯一的名字。Zookeeper 可以实现一套分布式全局唯一ID的分配机制。
分布式协调
在绝大多数分布式系统中,系统机器间的通信无外乎 心跳检测、工作进度汇报和系统调 度 。
分布式锁
排它锁又称为写锁或独占锁 ,若事务T1对数据对象O1加上了排它锁,那么在整个加锁期 间,只允许事务T1对O1进行读取和更新操作 ,其他任何事务都不能再对这个数据对象进行任 何类型的操作,直到T1释放了排它锁。
共享锁又称为读锁 ,若事务T1对数据对象O1加上共享锁,那么当前事务只能对O1进行读取操 作,其他事务也只能对这个数据对象加共享锁,直到该数据对象上的所有共享锁都被释放。 在需要获取共享锁时,所有客户端都会到/shared_lock下面创建一个临时顺序节点
zookeeper的架构
- leader只有一个,所有写操作只能leader完成
- follower可以多个,负责选举和读操作,如果是写操作,则需要转发给leader。
- observer与follower相似,但无投票权
zookeeper的选举是ZXID(事物id)和myid决定,只要设备选举过半,即可确定leader
zookeeper的命令
Znode的特点
-
Znode 的特点 文件系统的核心是 Znode
-
如果想要选取一个 Znode , 需要使用路径的形式, 例如 /test1/test11
-
Znode 本身并不是文件, 也不是文件夹, Znode 因为具有一个类似于 Name 的路径, 所以可 以从逻辑上实现一个树状文件系统
-
ZK 保证 Znode 访问的原子性, 不会出现部分 ZK 节点更新成功, 部分 ZK 节点更新失败的问 题
-
Znode 中数据是有大小限制的, 最大只能为 1M
-
Znode 是由三个部分构成 :stat,data,children
Znode的类型
持久,临时(不能有子节点),有序,无序
PERSISTENT:永久节点
EPHEMERAL:临时节点
PERSISTENT_SEQUENTIAL:永久节点、序列化 EPHEMERAL_SEQUENTIAL:临时节点、序列化
zookeeper的api操作
@Test
public void creatZnode() throws Exception {
//1.定制重试策略
RetryPolicy retryPolicy=new ExponentialBackoffRetry(1000, 1);
//2.获取客户端对象
/*
* 参数1:服务器列表
* 参数2:会话超时时间
* 参数3:链接超时时间
* 参数4:重试策略
* */
String connectionStr="121.196.109.0:2181,8.131.73.25:2181";
CuratorFramework client = CuratorFrameworkFactory.newClient(connectionStr, 8000, 8000, retryPolicy);
client.start();
//创建永久节点
//PERSISTENT:永久节点
//EPHEMERAL:临时节点
//PERSISTENT_SEQUENTIAL:永久节点、序列化
//EPHEMERAL_SEQUENTIAL:临时节点、序列化
//只能传入字节数组,查询zookeeper时,返回的额也是字节数组,所以需要将字节数组强制转换为字符串
client.create().creatingParentContainersIfNeeded().withMode(CreateMode.PERSISTENT).forPath("/hello1/hello","hello2".getBytes());
client.close();
}
}
修改节点数据
client.setData().forPath("/hello5", "hello7".getBytes());
节点数据查询
byte[] forPath = client.getData().forPath("/hello5");
watch机制
//watch机制
@Test
public void watchZnode() throws Exception {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 1);
String connectStr="121.196.109.0:2181,8.131.73.25:2181";
CuratorFramework cilent = CuratorFrameworkFactory.newClient(connectStr, 8000, 8000, retryPolicy);
cilent.start();
TreeCache treeCache = new TreeCache(cilent, "/hello2");
//自定义监听器
treeCache.getListenable().addListener(new TreeCacheListener() {
@Override
public void childEvent(CuratorFramework client, TreeCacheEvent event) throws Exception {
ChildData data = event.getData() ;
if(data !=null) {
switch (event.getType()) {
case NODE_ADDED:
System.out.println("监控到节点增加");
break;
case NODE_REMOVED:
System.out.println("监控到节点移除");
break;
case NODE_UPDATED:
System.out.println("监控到节点更新");
break;
}
}
}
});
treeCache.start();
Thread.sleep(5000000);