这里有新鲜出炉的 Java 设计模式,程序狗速度看过来!
Java 程序设计语言
java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的 Java 程序设计语言和 Java 平台(即 JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称.
ZooKeeper 是一个分布式的,开放源码的分布式应用程序协调服务,是 Google 的 Chubby 一个开源的实现,是 Hadoop 和 Hbase 的重要组件.下面通过本文给大家分享 java 中 zookeeper 简单使用,需要的朋友参考下吧
一,zookeeper 的基本原理
数据模型,如下:
ZooKeeper 数据模型的结构与 Unix 文件系统很类似,整体上可以看作是一棵树,每个节点称做一个 ZNode.每个 ZNode 都可以通过其路径唯一标识,比如上图中第三层的第一个 ZNode, 它的路径是 / app1/c1.在每个 ZNode 上可存储少量数据 (默认是 1M, 可以通过配置修改, 通常不建议在 ZNode 上存储大量的数据),这个特性非常有用.另外,每个 ZNode 上还存储了其 Acl 信息,这里需要注意,虽说 ZNode 的树形结构跟 Unix 文件系统很类似,但是其 Acl 与 Unix 文件系统是完全不同的,每个 ZNode 的 Acl 的独立的,子结点不会继承父结点的.
ZooKeeper 特性:1,读,写 (更新) 模式
在 ZooKeeper 集群中,读可以从任意一个 ZooKeeperServer 读,这一点是保证 ZooKeeper 比较好的读性能的关键;写的请求会先 Forwarder 到 Leader,然后由 Leader 来通过 ZooKeeper 中的原子广播协议,将请求广播给所有的 Follower,Leader 收到一半以上的写成功的 Ack 后,就认为该写成功了,就会将该写进行持久化,并告诉客户端写成功了.
2,WAL 和 Snapshot
和大多数分布式系统一样,ZooKeeper 也有 WAL(Write-Ahead-Log),对于每一个更新操作,ZooKeeper 都会先写 WAL, 然后再对内存中的数据做更新,然后向 Client 通知更新结果.另外,ZooKeeper 还会定期将内存中的目录树进行 Snapshot,落地到磁盘上,这个跟 HDFS 中的 FSImage 是比较类似的.这么做的主要目的,一当然是数据的持久化,二是加快重启之后的恢复速度,如果全部通过 ReplayWAL 的形式恢复的话,会比较慢.
3,FIFO
对于每一个 ZooKeeper 客户端而言,所有的操作都是遵循 FIFO 顺序的,这一特性是由下面两个基本特性来保证的:一是 ZooKeeperClient 与 Server 之间的网络通信是基于 TCP,TCP 保证了 Client/Server 之间传输包的顺序;二是 ZooKeeperServer 执行客户端请求也是严格按照 FIFO 顺序的.
4,Linearizability
在 ZooKeeper 中,所有的更新操作都有严格的偏序关系,更新操作都是串行执行的,这一点是保证 ZooKeeper 功能正确性的关键.
二,zookeeper 的常用命令
我们可以执行 zookeeper-client 或者执行 / opt/cloudera/parcels/CDH-5.0.0-1.cdh5.0.0.p0.47/lib/zookeeper/bin/zkCli.sh-server localhost,进入 zookeeper 命令行,如下:
然后,执行 ls / 可以看到:
然后,我们可以执行 create /qyktest'qyktest'创建一个节点,如下:
然后,我们执行 get /qyktest 获取节点值,如下:
然后,我们可以执行 set /qyktest'111'修改节点的值,如下:
最后,我们执行 delete /qyktest 便可删除此节点.
另外,我们还可以在 qyktest 此节点下继续创建子节点.
好了,几个基本命令就讲到这人啦,其它的命令还有很多,大家可以去查阅下资料.
三,zookeeper 的 javaapi 操作
关于 Javaapi 操作 zookeeper 比较简单,笔者直接贴出代码,如下:
packageorg.zookeeper.demo;
importjava.io.IOException;
importjava.util.concurrent.CountDownLatch;
importorg.apache.zookeeper.CreateMode;
importorg.apache.zookeeper.KeeperException;
importorg.apache.zookeeper.WatchedEvent;
importorg.apache.zookeeper.Watcher;
importorg.apache.zookeeper.Watcher.Event.KeeperState;
importorg.apache.zookeeper.ZooDefs.Ids;
importorg.apache.zookeeper.ZooKeeper;
publicclassZookeeperClientimplementsWatcher {
//连接超时时间,10s
privatestaticfinalintSESSION_TIMEOUT = 10000;
//连接的zookeeperserver
privatestaticfinalStringCONNECTION_STRING = "172.31.25.8:2181";
privatestaticfinalStringZK_PATH = "/qyktest";
privateZooKeeperzk = null;
privateCountDownLatchconnectedSemaphore = newCountDownLatch(1);
publicvoidcreateConnection(StringconnectString, intsessionTimeout) {
this.releaseConnection();
try {
zk = newZooKeeper(connectString, sessionTimeout, this);
connectedSemaphore.await();
} catch(InterruptedExceptione) {
System.out.println("连接创建失败,发生InterruptedException");
e.printStackTrace();
} catch(IOExceptione) {
System.out.println("连接创建失败,发生IOException");
e.printStackTrace();
}
}
publicvoidreleaseConnection() {
if (this.zk != null) {
try {
this.zk.close();
} catch(InterruptedExceptione) {
e.printStackTrace();
}
}
}
publicbooleancreatePath(Stringpath, String data) {
try {
Stringresult = this.zk.create(path, data.getBytes(), Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
System.out.println("节点创建成功,Path: " + result + ", content: " + data);
} catch(KeeperExceptione) {
System.out.println("节点创建失败,发生KeeperException");
e.printStackTrace();
} catch(InterruptedExceptione) {
System.out.println("节点创建失败,发生InterruptedException");
e.printStackTrace();
}
returntrue;
}
publicStringreadData(Stringpath) {
try {
System.out.println("获取数据成功,path:" + path);
returnnewString(this.zk.getData(path, false, null));
} catch(KeeperExceptione) {
System.out.println("读取数据失败,发生KeeperException,path:" + path);
e.printStackTrace();
return "";
} catch(InterruptedExceptione) {
System.out.println("读取数据失败,发生InterruptedException,path: " + path);
e.printStackTrace();
return "";
}
}
publicbooleanwriteData(Stringpath, String data) {
try {
System.out.println("更新数据成功,path:" + path + ", stat: " + this.zk.setData(path, data.getBytes(), -1));
} catch(KeeperExceptione) {
System.out.println("更新数据失败,发生KeeperException,path:" + path);
e.printStackTrace();
} catch(InterruptedExceptione) {
System.out.println("更新数据失败,发生InterruptedException,path: " + path);
e.printStackTrace();
}
returnfalse;
}
publicvoiddeleteNode(Stringpath) {
try {
this.zk.delete(path, -1);
System.out.println("删除节点成功,path:" + path);
} catch(KeeperExceptione) {
System.out.println("删除节点失败,发生KeeperException,path:" + path);
e.printStackTrace();
} catch(InterruptedExceptione) {
System.out.println("删除节点失败,发生InterruptedException,path: " + path);
e.printStackTrace();
}
}
publicstaticvoidmain(String[] args) {
ZookeeperClientsample = newZookeeperClient();
//获取连接
sample.createConnection(CONNECTION_STRING, SESSION_TIMEOUT);
//读数据
Stringqyk = sample.readData("/qyktest");
System.out.println("qyk:" + qyk);
Stringurl = sample.readData("/qyk/db/url");
System.out.println("url" + url);
Stringdriver = sample.readData("/qyk/db/driver");
System.out.println("driver" + driver);
StringuserName = sample.readData("/qyk/db/userName");
System.out.println("userName" + userName);
Stringpassword = sample.readData("/qyk/db/password");
System.out.println("password" + password);
//创建节点
sample.createPath(ZK_PATH, "我是节点初始内容");
System.out.println("数据内容:" + sample.readData(ZK_PATH) + "\n");
//更新节点
sample.writeData(ZK_PATH, "更新后的数据");
System.out.println("数据内容:" + sample.readData(ZK_PATH) + "\n");
//删除节点
sample.deleteNode(ZK_PATH);
//释放连接
sample.releaseConnection();
}@Override publicvoidprocess(WatchedEventevent) {
System.out.println("收到事件通知:" + event.getState() + "\n");
if (KeeperState.SyncConnected == event.getState()) {
connectedSemaphore.countDown();
}
}
}
然后,执行可以看到,控制台输出如下:
所以,像一些公用的配置,我们可以存到 zookeeper 里面,之后其它的服务就可以使用了
总结
以上所述是小编给大家介绍的 java 中 zookeeper 简单使用,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的.在此也非常感谢大家对 PHPERZ 网站的支持!
来源: http://www.phperz.com/article/18/0118/353254.html