官网:https://zookeeper.apache.org/
https://www.apache.org/dyn/closer.cgi/zookeeper/
实现一次更新处处更新
文件系统+通知机制
文件系统:目录树结构
linux命令:
ls - ltr :最近最新修改文件夹在最下方
cp -r 要拷贝的文件名/myzookeeper/ :直接将所有拷贝过去
每一个ZNode默认能够存储1MB的数据,
Znode= path+nodeValue+Stat
-s:代表自动序列,-e:代表临时,-p:(默认)持久persistent
可以同时使用 -s -e 和 -s -p
重启后:6和7两个临时节点消失了
总结:
zookeeper有四种类型的节点:
-s -p:持久化,序列化节点
-e: 临时节点
-p: 持久化节点
-s -e: 临时,序列化节点
zkCli的常用命令:
和redis的kv键值对类似,只不过key变成了一个path节点值,v就是data
一个节点对应一个应用,节点存储的数据就是应用需要的配置信息
delete只能删除当前节点,且下面不能有子节点
rmf递归删除,删除当前节点及其子节点
ls2:查看当前节点并能看到更新数据等数据
ZOOKEEPER支持常用的四字命令:
查看当前zookeeper的环境
zookeeper的helloworld:
public class HelloZK {
private static final Logger LOGGER = Logger.getLogger(String.valueOf(HelloZK.class));
private static final String CONNECT_STRING = "192.168.198.128:2181";
private static final int SESSION_TIMEOUT = 50*1000;
private static final String PATH = "/hellolixiang";
public ZooKeeper startZK() throws IOException {
return new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, new Watcher() {
public void process(WatchedEvent watchedEvent) {
}
});
}
public void stopZK(ZooKeeper zk) throws InterruptedException {
if (null != null){
zk.close();
}
}
public void createZnode(ZooKeeper zk,String nodePath,String nodeValue) throws KeeperException, InterruptedException {
zk.create(nodePath,nodeValue.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
public String getZnode(ZooKeeper zk,String nodePath) throws KeeperException, InterruptedException {
String result = null;
byte[] byteArray = zk.getData(nodePath, false, new Stat());
result = new String(byteArray);
return result;
}
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
HelloZK helloZK = new HelloZK();
ZooKeeper zk = helloZK.startZK();
if (zk.exists(PATH,false)==null){
helloZK.createZnode(zk,PATH,"helloZookeeper0412");
String retValue = helloZK.getZnode(zk, PATH);
LOGGER.info("*************retValue"+retValue);
}else {
LOGGER.info("************I have this node!");
}
helloZK.stopZK(zk);
}
}
watch:(差不多相当于redis的哨兵)
getData(),getChildren()和exists()都有设置watch的选项
一次性watch:
public class WatchOne {
private static final Logger LOGGER = Logger.getLogger(String.valueOf(WatchOne.class));
//常量
private static final String CONNECT_STRING = "192.168.198.128:2181";
private static final int SESSION_TIMEOUT = 50*1000;
private static final String PATH = "/lixiang";
//实例变量
private ZooKeeper zk = null;
public ZooKeeper startZK() throws IOException {
return new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, new Watcher() {
public void process(WatchedEvent watchedEvent) {
}
});
}
public void createZnode(String nodePath,String nodeValue) throws KeeperException, InterruptedException {
zk.create(nodePath,nodeValue.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
public String getZnode(String nodePath) throws KeeperException, InterruptedException {
String result = null;
byte[] byteArray = zk.getData(nodePath, new Watcher() {
public void process(WatchedEvent watchedEvent) {
try {
trigerValue(PATH);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, new Stat());
result = new String(byteArray);
return result;
}
private String trigerValue(String nodePath) throws KeeperException, InterruptedException {
String result = null;
byte[] byteArray = zk.getData(PATH, false, new Stat());
result = new String(byteArray);
LOGGER.info("**************watch one time :"+result);
return result;
}
public ZooKeeper getZk() {
return zk;
}
public void setZk(ZooKeeper zk) {
this.zk = zk;
}
/**
* 监控我们的/lixiang节点,获得初次值后设置watch,只要发生新的变化,打印出最新的值,一次性watch
* @param args
* @throws IOException
* @throws InterruptedException
* @throws KeeperException
*/
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
WatchOne watchOne = new WatchOne();
watchOne.setZk(watchOne.startZK());
if (watchOne.getZk().exists(PATH,false)==null){
watchOne.createZnode(PATH,"AAA");
String retValue = watchOne.getZnode(PATH);
LOGGER.info("*****************first retValue:"+retValue);
Thread.sleep(Long.MAX_VALUE);
}else {
LOGGER.info("****************node ok!");
}
}
}
第一次set的时候:控制监控到了
第二次修改:没有监控到,所以是一次性监控
public class WatchMore {
private static final Logger LOGGER = Logger.getLogger(String.valueOf(WatchMore.class));
//常量
private static final String CONNECT_STRING = "192.168.198.128:2181";
private static final int SESSION_TIMEOUT = 50*1000;
private static final String PATH = "/lixiang";
//实例变量
private ZooKeeper zk = null;
private String oldValue = null;
public ZooKeeper startZK() throws IOException {
return new ZooKeeper(CONNECT_STRING, SESSION_TIMEOUT, new Watcher() {
public void process(WatchedEvent watchedEvent) {
}
});
}
public void createZnode(String nodePath,String nodeValue) throws KeeperException, InterruptedException {
zk.create(nodePath,nodeValue.getBytes(), ZooDefs.Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
}
public String getZnode(String nodePath) throws KeeperException, InterruptedException {
String result = null;
byte[] byteArray = zk.getData(nodePath, new Watcher() {
public void process(WatchedEvent watchedEvent) {
try {
trigerValue(PATH);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, new Stat());
result = new String(byteArray);
oldValue = result;
return result;
}
private Boolean trigerValue(final String nodePath) throws KeeperException, InterruptedException {
String result = null;
byte[] byteArray = zk.getData(PATH, new Watcher() {
public void process(WatchedEvent watchedEvent) {
try {
trigerValue(nodePath);
} catch (KeeperException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, new Stat());
result = new String(byteArray);
String newValue = result;
if (oldValue.equals(newValue)){
LOGGER.info("*********no changes*****");
return false;
}else {
LOGGER.info("********oldValue:"+oldValue+"\t newValue:"+newValue);
oldValue = newValue;
return true;
}
}
public String getOldValue() {
return oldValue;
}
public void setOldValue(String oldValue) {
this.oldValue = oldValue;
}
public ZooKeeper getZk() {
return zk;
}
public void setZk(ZooKeeper zk) {
this.zk = zk;
}
/**
* 监控我们的/lixiang节点,获得初次值后设置watch,只要发生新的变化,打印出最新的值,一次性watch
* @param args
* @throws IOException
* @throws InterruptedException
* @throws KeeperException
*/
public static void main(String[] args) throws IOException, InterruptedException, KeeperException {
WatchMore watchMore = new WatchMore();
watchMore.setZk(watchMore.startZK());
if (watchMore.getZk().exists(PATH,false)==null){
watchMore.createZnode(PATH,"AAA");
String retValue = watchMore.getZnode(PATH);
LOGGER.info("*****************first retValue:"+retValue);
Thread.sleep(Long.MAX_VALUE);
}else {
LOGGER.info("****************node ok!");
}
}
}
监控字节点:
/lixiang:该路径下的子节点发生变化,都会打印,增加和减少
只有根节点/下面的子节点发生变化才会,打印
zookeeper集群:
1.复制文件:
2.建文件夹:
3.改配置文件:
4.建立主从关系: