zookeeper是什么
zookepper是hadoop的一个子项目,Apache软件基金会下的一个项目,用于分布式程序的协调服务。具体是什么呢?打个比方,我们可以把整个分布式应用程序想象成一个人,分布式应用程序由不同服务组成,就好比一个人由不同的器官组成,比如一个人有头,有手,有脚,眼睛,鼻子等。那么zookeeper在分布式系统中充当一个什么角色呢?我们可以把zookeeper想象成人体中的大脑,负责协调人体的不同器官。
zookeeper的应用场景
1.数据的发布与订阅
发布者将数据发布出来,订阅者通过一定的方式获取到这些数据。ZooKeeper采用推模式和拉模式两种方式结合的方式。发布者将数据发布到zk集群节点上,订阅者通过一定的方法告诉服务器,我对哪个节点的数据感兴趣,那服务器在这些节点的数据发生变化时,就通知客户端,客户端得到通知后可以去服务器获取数据信息。
2.负载均衡
举个例子,DB或者某个服务在启动的时候会在zookeeper上注册一个临时节点,zookeeper中有两种节点类型,一种是永久节点,另一种是临时节点,如果在启动的时候出现问题,那么该服务在zookeeper上注册的节点就会自动删除,这样在zookeeper中就会保留最新的并且可用的节点。
客户端需要在数据库中读写数据时,首先需要在zookeeper中获取数据库的可用的连接信息,然后客户端会随机选择一个建立连接,当发现这个连接不可用时,客户读会再次到zookeeper中获取可用的连接信息,也可以在zookeeper中删除这个不可用的连接再建立一个新的连接。
3.分布式协调通知
在zookeeper中判断某个服务是否可用,是通过判断这个服务在zookeeper中创建的一个临时节点是否存在,如果这个临时节点不存在说明这个服务不可用,相反可用。
4.命名服务
命名服务就是提供名称的服务,Zookeeper的命名服务有两个应用方面。一个是提供类似JNDI功能,另一个是制作分布式的序列号生成器。
zookeeper原始api的使用
package com.weibaoer;
import org.apache.zookeeper.*;
import java.io.IOException;
import java.util.concurrent.CountDownLatch;
public class ZookeeperNativeApi implements Watcher {
private static final String PARENT_PATH="/parent";
private static final String CHILD_PATH="/child";
private static final String PARENT_DATA="parent";
private static final String CHILD_DATA="child";
private static final Integer SESSION_TIMEOUT=5000;
private static final String CONNECT_URL="127.0.0.1:2181";
private ZooKeeper zookeeper;
private CountDownLatch countDownLatch=new CountDownLatch(1);
public void createConnect(){
try {
zookeeper=new ZooKeeper(CONNECT_URL,SESSION_TIMEOUT,this);
countDownLatch.await();
} catch (Exception e) {
e.printStackTrace();
}
}
public void close(){
if(zookeeper!=null){
try {
zookeeper.close();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public void create(String path,String data,Boolean needWatch){
try {
zookeeper.exists(path,needWatch);
String root = zookeeper.create(path, data.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println(root);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void delete(String path,Boolean needWatch){
try {
zookeeper.exists(path,needWatch);
zookeeper.delete(path,-1);
} catch (InterruptedException e) {
e.printStackTrace();
} catch (KeeperException e) {
e.printStackTrace();
}
}
public void setData(String path,Boolean needWatch){
try {
zookeeper.exists(path,needWatch);
zookeeper.setData(path,"hello".getBytes(),-1);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void process(WatchedEvent watchedEvent) {
try {
countDownLatch.countDown();
} catch (Exception e) {
e.printStackTrace();
}
if(watchedEvent==null){
return;
}
String path = watchedEvent.getPath();
Event.KeeperState state = watchedEvent.getState();
Event.EventType type = watchedEvent.getType();
if(state==Event.KeeperState.SyncConnected){
if(type==Event.EventType.None){
System.out.println("连接成功!");
}else if(type==Event.EventType.NodeCreated){
System.out.println("创建节点:"+path);
}else if(type==Event.EventType.NodeDataChanged){
System.out.println("更新节点:"+path);
}else if(type==Event.EventType.NodeChildrenChanged){
System.out.println("孩子节点变化:"+path);
}
}else{
System.out.println("连接失败!");
}
}
public static void main(String[] args) {
ZookeeperNativeApi zookeeperWatch=new ZookeeperNativeApi();
zookeeperWatch.createConnect();
zookeeperWatch.create(PARENT_PATH,PARENT_DATA,false);
zookeeperWatch.close();
}
}
curator使用
package com.weibaoer;
import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.data.Stat;
import java.util.List;
public class ZookeeperCuratorApi {
//zookeeper的连接地址
private static final String CONNECT_STRING="127.0.0.1:2181";
//zookeeper的session过期时间
private static final Integer SESSION_TIMEOUT=5000;
//重试策略:初试时间为1s 重试10次
private static final RetryPolicy retryPolicy=new ExponentialBackoffRetry(1000,10);
private CuratorFramework curatorFramework;
//创建一个连接
public void createConnect(){
//链式编程创建一个curatorFramework对象
curatorFramework=CuratorFrameworkFactory.builder()
.connectString(CONNECT_STRING)
.sessionTimeoutMs(SESSION_TIMEOUT)
.retryPolicy(retryPolicy)
.build();
//开启一个连接
curatorFramework.start();
// System.out.println(ZooKeeper.States.CONNECTED);
//获取链接状态
System.out.println(curatorFramework.getState());
}
//释放连接
public void releaseConnect(){
if(curatorFramework!=null){
curatorFramework.close();
}
}
//通过curatorFramework对象创建一个节点
public void createNode(String path,String data){
//4 建立节点 指定节点类型(不加withMode默认为持久类型节点)、路径、数据内容
try {
curatorFramework.create()
.creatingParentsIfNeeded()
.withMode(CreateMode.PERSISTENT)
.forPath(path,data.getBytes());
} catch (Exception e) {
e.printStackTrace();
}
}
//删除节点
public void delete(String path){
try {
curatorFramework.delete()
.guaranteed()
.deletingChildrenIfNeeded()
.forPath(path);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取节点数据
public void getData(String path){
try {
byte[] datas = curatorFramework.getData().forPath(path);
System.out.println(new String(datas,"UTF-8"));
} catch (Exception e) {
e.printStackTrace();
}
}
//更新节点数据
public void setData(String path,String data){
try {
curatorFramework.setData().forPath(path, data.getBytes("UTF-8"));
} catch (Exception e) {
e.printStackTrace();
}
}
//获取某个节点的子节点
public void getChildren(String path){
try {
List<String> childNodes = curatorFramework.getChildren().forPath(path);
for (String node:childNodes) {
System.out.println(node);
}
} catch (Exception e) {
e.printStackTrace();
}
}
//判断某个节点是否存在
public void checkNodeExists(String path){
try {
Stat stat = curatorFramework.checkExists().forPath(path);
System.out.println(stat);
} catch (Exception e) {
e.printStackTrace();
}
}
//删除子节点
public void deleteChilds(String path){
try {
curatorFramework.delete()
.guaranteed()
.deletingChildrenIfNeeded()
.forPath(path);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ZookeeperCuratorApi zookeeperCuratorApi=new ZookeeperCuratorApi();
zookeeperCuratorApi.createConnect();
zookeeperCuratorApi.createNode("/super/c1","111111");
zookeeperCuratorApi.createNode("/super/c2","222222");
zookeeperCuratorApi.checkNodeExists("/super");
zookeeperCuratorApi.getData("/super/c1");
zookeeperCuratorApi.setData("/super/c1","333333");
zookeeperCuratorApi.getData("/super/c1");
// zookeeperCuratorApi.deleteChilds("/super");
zookeeperCuratorApi.delete("/super");
zookeeperCuratorApi.releaseConnect();
}
}