Zookeeper基础入门
Zookeeper简介
基本概念
Zookeeper是一个开源的分布式协调服务。其设计目标是将那些复杂的容易出错的分布式一致性服务封装起来,以简单的接口提供给用户使用。它是一个典型的分布式数据一致性的解决方案,分布式应用程序可以基于它实现如:发布/订阅、负载均衡、集群管理、分布式锁、分布式队列等功能。
名词概念
- 集群角色
Zookeeper集群中有三种角色:Leader、Follower、Observer。Leader提供读和写服务。Follower和Observer能提供读服务。Observer和Follower的区别就在于Ovserver不参与Leader选举,不参与写操作的过半成功策略。
因此Observer可以在不影响写性能的情况下,提升集群的性能。如果没有Observer的话,一个Leader和N个Follower,如果Follower特别多的话,虽然读性能提高了,但是写性能和选举的性能会受影响。
- 会话(session)
客户端会话,一个客户端连接是指客户端和服务端之间的一个TCP长连接。客户端启动的时候,首先会和服务器建立一个TCP长连接,从第一次建立连接开始,会话(session)的生命周期就开始了。通过这个连接,客户端能够通过心跳检测与服务器保持有效的会话,也能够向Zookeeper服务器发送请求,同时还能接受服务器的Watch事件通知。
- 数据节点(Znode)
Zookeeper数据模型中的一个单元,我们称之为数据节点。Zookeeper将所有数据存储在内存中,数据模型是一棵树,由斜杠进行分割的路径,就是一个Znode。如/app。每个Znode都能保存自己的数据内容,还会保存属性信息。
4. 版本
每个Znode都有一个叫作Stat的数据结构,Stat里记录了Znode的三个数据版本,分别是version(当前Znode的版本)、cversion(当前Znode子节点的版本)、aversion(当前Znode的ACL版本)
5. Watcher(事件监听器)
Watcher是Zookeeper中一个很重要的特性,Zookeeper允许用户在指定节点上注册一些Watcher,并且在一些特定事件触发的时候,Zookeeper服务端会将事件通知到感兴趣的客户端,该机制是Zookeeper实现分布式协调服务的重要特性。
6. ACL
Zookeeper采用ACL策略来进行权限控制,它定义了五种权限:
- CREATE:创建子节点的权限
- READ:获取节点数据和子节点列表的权限
- WRITE:更新节点数据的权限
- DELETE:删除子节点的权限
- ADMIN:设置子节点ACL的权限。
注意:CREATE和DELETE这两种权限是针对子节点的权限控制
Zookeeper命令行
- 客户端连接
./zkCli.sh #连接本地的zookeeper服务器
./zkCli.sh -server ip:port # 连接远程的服务器
连接成功之后,系统会输出Zookeeper的相关环境及配置信息等信息
- 创建节点
create [-s] [-e] [-c] [-t ttl] path [data] [acl]
#创建顺序节点
create -s /cc
#创建临时节点,客户端会话结束后,节点会自动删除
create -e /temp
#创建带内容的节点
create /hi nihao
- 读取节点
#ls命令会列出path节点下所有的子节点
ls path
#get命令会查询到path节点的数据内容,加上-s可以查询更详细的信息
get [-s] path
- 更新节点
set [-s] [-v version] path data
#修改/abc节点的内容为hello,加上-s会返回更详细的信息
set /abc hello
- 删除节点
#删除,如果带上了版本参数,那么删除的时候就会校验版本是否正确,正确才进行删除
delete [-v version] path
Zookeeper 客户端API
官方原生API
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.14</version>
</dependency>
很少直接使用了,接口介绍省略
ZkClient API
ZkClient是github上一个开源的zookeeper客户端,在原生API的基础上进行了包装,更加易用。同时还实现了如Session超时重连、Watcher反复注册等功能。
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.2</version>
</dependency>
直接上代码:
public class ClientDemo {
private static final String connectStr="192.168.56.115:2181";
public static void main(String[] args) throws InterruptedException {
// create();
// delete();
// get();
getData();
}
public static void create() throws InterruptedException {
ZkClient zkClient=new ZkClient(connectStr);
//第二个参数,true代表递归创建节点,没有父节点先创建父节点
zkClient.createPersistent("/test/node01",true);
//持久有序的node
zkClient.createPersistentSequential("/test/node02","data");
//临时node
zkClient.createEphemeral("/ephemeral");
}
public static void delete(){
ZkClient zkClient=new ZkClient(connectStr);
//普通删除
zkClient.delete("/test");
//遍历删除,先删除该节点的所有子节点,再删除它本身
zkClient.deleteRecursive("/test");
}
public static void get() throws InterruptedException {
ZkClient zkClient=new ZkClient(connectStr);
List<String> children = zkClient.getChildren("/test");
System.out.println("子节点:"+children);
zkClient.subscribeChildChanges("/watch", new IZkChildListener() {
@Override
public void handleChildChange(String s, List<String> list) throws Exception {
System.out.println(s + " child changed,list:" + list);
}
});
zkClient.createPersistent("/watch");
Thread.sleep(1000);
zkClient.createPersistent("/watch/test");
Thread.sleep(1000);
zkClient.delete("/watch/test");
Thread.sleep(1000);
zkClient.delete("/watch");
}
//获取数据
public static void getData() throws InterruptedException {
ZkClient zkClient=new ZkClient(connectStr);
String path="/abc";
boolean exists = zkClient.exists(path);
System.out.println("节点是否存在:"+exists);
if(!exists){
zkClient.createEphemeral(path,"123");
}
//数据改变监听
zkClient.subscribeDataChanges(path, new IZkDataListener() {
@Override
public void handleDataChange(String s, Object o) throws Exception {
System.out.println("节点:"+s+" 数据被改变:"+o);
}
@Override
public void handleDataDeleted(String s) throws Exception {
System.out.println("节点被删除:"+s);
}
});
//读取数据
Object o = zkClient.readData(path);
System.out.println("读取节点的数据:"+o);
Thread.sleep(3000);
//更新数据
Stat stat = zkClient.writeData(path, "456");
Thread.sleep(3000);
//删除数据
zkClient.delete(path);
Thread.sleep(3000);
}
}
Curator API
Curator是Netflix公司开源的客户端框架。它实现了连接重连、Watcher反复注册、重试策略和NodeExistsException异常解决等等。
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>2.12.0</version>
</dependency>
直接上代码:
public class CuratorDemo {
private static final String connectStr="192.168.56.115:2181";
private static String path ="/abc";
public static void main(String[] args) throws Exception {
// connect();
// create();
// delete();
// get();
update();
}
public static void connect(){
//连接方式1
/*
构造器含有三个参数 ExponentialBackoffRetry(int
baseSleepTimeMs, int maxRetries, int maxSleepMs)
baseSleepTimeMs:初始的sleep时间,⽤于计算之后的每次重试的sleep时间,
计算公式:当前sleep时间=baseSleepTimeMs*Math.max(1,
random.nextInt(1<<(retryCount+1)))
maxRetries:最⼤重试次数
maxSleepMs:最⼤sleep时间,如果上述的当前sleep计算出来⽐这个⼤,那么sleep⽤
这个时间,默认的最⼤时间是Integer.MAX_VALUE毫秒。
*/
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.newClient(connectStr, 5000, 3000, retryPolicy);
client.start();
//连接方式2
CuratorFramework Client = CuratorFrameworkFactory.builder()
.connectString("server1:2181,server2:2181,server3:2181")
.sessionTimeoutMs(50000)
.connectionTimeoutMs(30000)
.retryPolicy(retryPolicy)
.build();
client.start();
}
public static void create() throws Exception {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.newClient(connectStr, 5000, 30000, retryPolicy);
client.start();
Thread.sleep(2000);
//创建一个内容为空的节点,curator默认是创建持久节点
// client.create().forPath(path);
//创建一个有内容的节点
client.create().forPath(path,"123".getBytes());
//调用creatingParentsIfNeeded 接口,Curator 就能够自动地递归创建所有需要的父节点
client.create().creatingParentsIfNeeded().withMode(CreateMode.EPHEMERAL).forPath("/tt");
}
public static void delete() throws Exception {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.newClient(connectStr, 5000, 30000, retryPolicy);
client.start();
//删除节点
client.delete().forPath(path);
//删除节点,并递归删除子节点
client.delete().deletingChildrenIfNeeded().forPath(path);
//指定版本删除ls
client.delete().withVersion(1).forPath(path);
//强制删除。只要客户端会话有效,那么Curator会在后台持续进⾏删除操作,直到节点删除成功。⽐如遇到⼀些⽹
//络异常的情况,此guaranteed的强制删除就会很有效果
client.delete().guaranteed().forPath(path);
}
public static void get() throws Exception {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.newClient(connectStr, 5000, 30000, retryPolicy);
client.start();
//普通查询
byte[] bytes = client.getData().forPath(path);
System.out.println("节点内容:"+new String(bytes));
// 包含状态查询
Stat stat = new Stat();
byte[] bytes1 = client.getData().storingStatIn(stat).forPath(path);
System.out.println(stat.getVersion());
}
public static void update() throws Exception {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.newClient(connectStr, 5000, 30000, retryPolicy);
client.start();
// 普通更新
client.setData().forPath(path,"新内容".getBytes());
// 指定版本更新 当携带数据版本不⼀致时,无法完成更新操作
// 异常信息:Exception in thread "main" org.apache.zookeeper.KeeperException$BadVersionException: KeeperErrorCode = BadVersion for /abc
client.setData().withVersion(1).forPath(path,"abcd".getBytes());
}
Zookeeper基础入门的更多相关文章
- ZooKeeper 基础入门
什么是ZooKeeper Apache ZooKeeper 是一个开源的实现高可用的分布式协调服务器.ZooKeeper是一种集中式服务,用于维护配置信息,域名服务,提供分布式同步和集群管理.所有这些 ...
- Zookeeper基础入门介绍
什么Zookeeper Zookeeper是一个分布式开源框架,提供了协调分布式应用的基本服务,它向外部应用暴露一组通用服务——分布式同步(Distributed Synchronization).命 ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- 「译」JUnit 5 系列:基础入门
原文地址:http://blog.codefx.org/libraries/junit-5-basics/ 原文日期:25, Feb, 2016 译文首发:Linesh 的博客:JUnit 5 系列: ...
- .NET正则表达式基础入门
这是我第一次写的博客,个人觉得十分不容易.以前看别人写的博客文字十分流畅,到自己来写却发现十分困难,还是感谢那些为技术而奉献自己力量的人吧. 本教程编写之前,博主阅读了<正则指引>这本入门 ...
- 从零3D基础入门XNA 4.0(2)——模型和BasicEffect
[题外话] 上一篇文章介绍了3D开发基础与XNA开发程序的整体结构,以及使用Model类的Draw方法将模型绘制到屏幕上.本文接着上一篇文章继续,介绍XNA中模型的结构.BasicEffect的使用以 ...
- 从零3D基础入门XNA 4.0(1)——3D开发基础
[题外话] 最近要做一个3D动画演示的程序,由于比较熟悉C#语言,再加上XNA对模型的支持比较好,故选择了XNA平台.不过从网上找到很多XNA的入门文章,发现大都需要一些3D基础,而我之前并没有接触过 ...
- Shell编程菜鸟基础入门笔记
Shell编程基础入门 1.shell格式:例 shell脚本开发习惯 1.指定解释器 #!/bin/bash 2.脚本开头加版权等信息如:#DATE:时间,#author(作者)#mail: ...
- [Spring框架]Spring AOP基础入门总结二:Spring基于AspectJ的AOP的开发.
前言: 在上一篇中: [Spring框架]Spring AOP基础入门总结一. 中 我们已经知道了一个Spring AOP程序是如何开发的, 在这里呢我们将基于AspectJ来进行AOP 的总结和学习 ...
随机推荐
- F2BPM的流程仿真
仿真概述 F2BPM工作流仿真是一种通过建立工作流虚拟运行环境执行工作流仿真的方法.集中式仿真引擎解释工作流仿真模型,仿真活动的执行,处理仿真过程中的不确定性,从而完成工作流模型的仿真.同时,会实时显 ...
- 论文解读GCN 1st《 Deep Embedding for CUnsupervisedlustering Analysis》
论文信息 Tittle:<Spectral Networks and Locally Connected Networks on Graphs> Authors:Joan Bruna.Wo ...
- 羽夏看Win系统内核——进程线程篇
写在前面 此系列是本人一个字一个字码出来的,包括示例和实验截图.由于系统内核的复杂性,故可能有错误或者不全面的地方,如有错误,欢迎批评指正,本教程将会长期更新. 如有好的建议,欢迎反馈.码字不易, ...
- 访问者模式(Visitor模式)
模式的定义与特点 访问者(Visitor)模式的定义:将作用于某种数据结构中的各元素的操作分离出来封装成独立的类,使其在不改变数据结构的前提下可以添加作用于这些元素的新的操作,为数据结构中的每个元素提 ...
- 学习Java第11天
今天所做的工作: 敲代码,按照教材进度,我已经"学完了",用引号引起来. 明天工作安排: 敲代码 所遇到的困难及解决方法: 虽然是"学完了",但真正写起来还是有 ...
- 2.flink
Flink 运行时的组件 作业管理器(JobManager) •控制一个应用程序执行的主进程,也就是说,每个应用程序都会被一个不同的JobManager 所控制执行. •JobManager 会先接收 ...
- 《Spring Boot 实战纪实》之过滤器
导航 什么是过滤器 Spring的过滤器 Filter定义 过滤的对象 典型应用 过滤器的使用 Filter生命周期 过滤器链 自定义敏感词过滤器 新增自定义过滤器 添加 @WebFilter注解 添 ...
- Vue 面试题
1.Vue父组件向子组件传递数据? 答:props传参 父组件 <child :list="list"></child> //在这里绑定list对象 子组件 ...
- 普通web项目一直无法访问页面,直接报404
错误:普通web项目一直无法访问页面,直接报404 原因:写了一个过滤乱码的类: 而在类上加了WebServlet注解,其实应该是WebFilter注解, 总结:基础不扎实,有些东西只会用,而不知道原 ...
- UIView属性的讲解
1.父控件和子控件的理解在storyboard中只有UIView是可以在里面拖入子控件的,其他控件不可以(必须通过代码添加)拖入一个UIView控件,在里面添加一些子控件(UIView控件是控制器的V ...