0
点赞
收藏
分享

微信扫一扫

zookeeper入门简介


zookeeper产生的背景

在分布式协调技术方面做得比较好的就是Google的Chubby还有Apache的ZooKeeper他们都是分布式锁的实现者。有人会问既然有了Chubby为什么还要弄一个ZooKeeper,难道Chubby做得不够好吗?不是这样的,主要是Chbby是非开源的,Google自家用。后来雅虎模仿Chubby开发出了ZooKeeper,也实现了类似的分布式锁的功能,并且将ZooKeeper作为一种开源的程序捐献给了Apache

#####zookeeper定位

Zookeeper是一个开源的,分布式的,为分布式应用提供协调服务的apache项目

zookeeper的特点

1. Zookeeper:一个Leader,多个Follwer组成的集群
2. 集群只要有半数以上的节点存活,集群就能正常服务(所以zookeeper集群一般都是奇数台,偶数台无意义)
3. 全局数据一致,每个server保存相同的数据副本
4. 更新请求顺序进行,同一个client的请求,按照顺序执行
5. 数据更新原子性
6. 实时性

zookeeper工作机制

Zookeeper 从设计模式角度来看,是一个基于观察者模式设计的分布式服务管理框架,它负责存储和管理
大家都关心的数据,然后接受观察者的注册,一旦这些数据的状态发生变化,Zookeeper 就将负责通知已
经在 Zookeeper 上注册的那些观察者做出相应的反应,从而实现集群中类似 Master/Slave 管理模式

ZooKeeper所提供的服务主要是通过:数据结构+原语+watcher机制

数据结构
  1. zookeeper数据模型的结构和Unix文件系统很类似,采用属性层次结构,每个节点都成为Znode,和文件
    系统的目录树一样,
  2. zookeeper树中每个节点可以拥有子节点,默认存储空间1MB系统的目录树一样,zookeeper树中每个 节点可以拥有子节点,默认存储空间1MBzookeeper树中每个节点可以拥有子节点,

zookeeper入门简介_zookeeper写数据

shell命令

help: 帮助命令
ls path :显示当前znode节点所包含的内容
ls2 path:查看当前节点数据并能看更多的详细数据
create 创建节点
- s :含有序列
- e : 临时创建(重启或超时消失)
get path: 获取节点值
set :设置节点的具体指
stat: 查看节点状态
delete :删除节点
rmr :递归删除节点

客户端启动:bin/zkCli.sh //zookeeper目录下

监听节点值的变化

get /XXX watch 

监听某个路径的变化

la /XXX watch

API应用

package month01.zookeeper;

import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.data.Stat;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.List;
@SuppressWarnings("all")
public class TestZookeeperCli {
private static final String connectString = "hadoop102:2181,hadoop103:2181,hadoop105:2181";
//将zookeeper客户端对象提出,变为成员变量
ZooKeeper zooKeeper = null;
//@before
@Before
public void test() throws IOException {
zooKeeper = new ZooKeeper(connectString,
2000,
new Watcher() {
@Override
public void process(WatchedEvent event) {
//通过event参数可以获取
System.out.println("changed....."+event.getPath()
+event.getState()
+event.getType()
);
}
});
}

/**
* 显示某路径下所有数据 ls
*/
@Test
public void testls(){
try {
//可以增加监听方式,如果新增了一个watcher(),就不会用调用zookeeper中的
List<String> children = zooKeeper.getChildren("/",new Watcher(){
//注册一次,使用一次就完成,如果希望一直监听,需要递归进行注册
@Override
public void process(WatchedEvent event) {
System.out.println("根目录发生变化");
}
});

//查找/路径,是否watch是否监听
for (String child : children) {
System.out.println(child);
}
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

//sleep() --静态方法,调用对象是当前main主线程
try {
Thread.sleep(Long.MAX_VALUE);
} catch (InterruptedException e) {
e.printStackTrace();
}
}

/**
* 递归进行注册方式,一直进行监听路径下状态
*/
@Test
public void get() throws KeeperException, InterruptedException {
byte[] data = zooKeeper.getData("/test", new Watcher() {
@Override
public void process(WatchedEvent event) {
//先发送消息,进行通知,在进行递归注册
System.out.println("/test 发生改变...");
try {
get();
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, new Stat());

System.out.println(data.toString());
}

@Test
public void getNow(){
try {
get();
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}

写数据流程

1.client向zookeeper的server1写数据,发送一个写请求
2.如果server1不是leader,server1会把接收到的请求进一步转交给leader,
因为每个zookeeper的server里面有一个leader,这个leader会将写请求广播给各个
server,比如server和server2,各个server写成功后就会通知leader
3.当leader收到大多数server数据写成功了,那么久认为数据写成功了,写成功后,
leader会告诉server1写数据成功
4.server1会进一步通知client数据写成功了,==》整个写操作成功


举报

相关推荐

0 条评论