目录
zookeeper
什么是zookeeper
Zookeeper是一个高效的分布式协调服务
zookeeper可以做什么
可以提供配置信息管理、命名、分布式同步、集群管理、数据库切换等服务。
可以用来存储一些配置、发布与订阅等少量信息。Hadoop、Storm、消息中间件、RPC服务框架、分布式数据库同步系统,这些都是Zookeeper的应用场景。
zookeeper不适合做什么
它不适合用来存储大量信息
zookeeper概述
Zookeeper集群中节点个数一般为奇数个(>=3),若集群中Master挂掉,剩余节点个数在半数以上时,就可以推举新的主节点,继续对外提供服务。
zookeeper的具体执行方式
简要概述:
-
客户端发起事务请求,事务请求的结果在整个Zookeeper集群中所有机器上的应用情况是一致的(也是一种去中心化的体现,对我们所表现出来的都是一致的,但实际上zookeeper自己本身有leader和follower)。不会出现集群中部分机器应用了该事务,而存在另外一部分集群中机器没有应用该事务的情况。在Zookeeper集群中的任何一台机器,其看到的服务器的数据模型是一致的。Zookeeper能够保证客户端请求的顺序,每个请求分配一个全局唯一的递增编号,用来反映事务操作的先后顺序。Zookeeper将全量数据保存在内存中,并直接服务于所有的非事务请求,在以读操作为主的场景中性能非常突出。(有相同的操作了,就不会再执行一次,就会把上面的结果拿过来)
-
Zookeeper使用的数据结构为树形结构,根节点为"/"。Zookeeper集群中的节点,根据其身份特性分为leader、follower、observer。leader负责客户端writer类型的请求;follower负责客户端reader类型的请求,并参与leader选举;observer是特殊的follower,可以接收客户端reader请求,但是不会参与选举,可以用来扩容系统支撑能力,提高读取速度。(reader读节点效率不够的时候,再加observer)
如何进行主备切换:
- Zookeeper是一个基于观察者(理解为一个监听)模式设计的分布式服务管理框架,负责存储和管理相关数据,接收观察者的注册。一旦这些数据的状态发生变化,zookeeper就负责通知那些已经在zookeeper集群进行注册并关心这些状态发生变化的观察者,以便观察者执行相关操作。(有几个节点,就有几个观察者)
- Zookeeper使用的是ZAB原子消息广播协议,节点之间的一致性算法为Paxos,能够保障分布式环境中数据的一致性。分布式场景下高可用是Zookeeper的特性,可以采用第三方客户端的实现,即Curator框架。
JavaAPI操作zookeeper(以Hadoop作为应用场景)
创建永久性节点
CreateMode.PERSISTENT 永久性节点
//创建zookeeper连接
//三台机器,给三个端口
ZooKeeper zooKeeper = new ZooKeeper(
"master:2181,node1:2181,node2:2181",3000,null
);
String s = zooKeeper.create("/show", "show".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT);
创建临时节点
CreateMode.EPHEMERAL 临时节点,会话断开或过期时会删除此节点
程序一结束,会话就断开了,就给上一个循环,让它不断开
//创建zookeeper连接
//三台机器,给三个端口
ZooKeeper zooKeeper = new ZooKeeper(
"master:2181,node1:2181,node2:2181",3000,null
);
String s = zooKeeper.create("/show1", "show1".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL);
while (true){
}
获取节点
//获取节点
Stat stat = new Stat();
byte[] data = zooKeeper.getData(
"/show", true, stat
);
for (byte datum : data) {
System.out.println(datum);
}
修改节点
//修改节点
Stat stat1 = zooKeeper.setData(
"/show", "showshow".getBytes(), -1
);
byte[] data1 = zooKeeper.getData(
"/show", true, stat1
);
for (byte b : data1) {
System.out.println(b);
}
创建子节点
//创建子节点
String s = zooKeeper.create(
"/show/show2", "data".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT
);
使用监听者监听节点的变化
ZooKeeper zooKeeper;
@Before
public void init() throws Exception{
//创建zookeeper连接
//三台机器,给三个端口
zooKeeper = new ZooKeeper(
"master:2181,node1:2181,node2:2181", 3000, null);
}
@Test
public void create() throws Exception{
//创建节点
String s = zooKeeper.create("/show1", "show1".getBytes(),
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.EPHEMERAL);
Thread.sleep(10000);
}
//手动创建监听
// (需要监控多少个节点,就有几个监听,
// 节点和监听一一对应,监听和节点有绑定的操作)
@Test
public void wacher(){
//获取当前子节点的对象,用来做绑定的
try {
zooKeeper.getChildren(
"/show1", new Watcher() {//这个监听者监听show,show发生改变,就返回回调函数
public void process(WatchedEvent watchedEvent) {
System.out.println("节点状态发生改变");
}
}
);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
//需要让它一直监听,就给一个循环不让它结束
while (true){
}
}
先启动create函数,创建一个临时节点,并且让线程休眠十秒,再启动wacher函数;线程休眠结束之后,观察监听器的状态,出现“节点状态发生改变”(通过这个小例子来展现回调)(监听器和节点是一一对应的,是绑定的)
感谢阅读,我是啊帅和和,一位大数据专业大四学生,祝你快乐。