2025年4月13日 星期日 乙巳(蛇)年 正月十四 设为首页 加入收藏
rss
您当前的位置:首页 > 计算机 > 服务器 > 万维网络 > 中间件

zookeeper入门到精通07——zookeeper客户端API节点操作与原理

时间:07-15来源:作者:点击数:37

一、监听节点

先看看怎么获取子节点,启动zookeeper服务集群。编写并运行如下测试案例。

  • public class ZKClient {
  • ZooKeeper client;
  • @Before
  • public void init() throws IOException {
  • // 注意逗号后不要加空格,严格按照格式,在下面写自己对应得zookeeper服务集群得ip
  • String connectString="192.168.106.43:2182,192.168.106.44:2182,192.168.106.45:2182";
  • // String connectString="192.168.106.43,192.168.106.44,192.168.106.45";
  • int sessionTimeout = 20000;
  • client = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
  • @Override
  • public void process(WatchedEvent watchedEvent) {
  • }
  • });
  • }
  • @Test
  • public void grtChild() throws InterruptedException, KeeperException {
  • // 参数true表示开启子节点的监听
  • List<String> children = client.getChildren("/", true);
  • for (String child: children) {
  • System.out.println(child);
  • }
  • }
  • }

上面并不能实时监听节点的变化,即使我们在使用getChildren是开启了子节点的监听。这是因为两个原因:第一,程序执行完一次监听后就退出了。第二,监听器注册一次只能够监听一次(参考:Zookeeper入门到精通05——Zookeeper客户端命令行操作,小节:监听器原理)。如何才能够实时监听子节点,并且一有变化就输出呢?很简单,把上面的代码稍微修改下即可。

  • public class ZKClient {
  • ZooKeeper client;
  • @Before
  • public void init() throws IOException {
  • // 注意逗号后不要加空格,严格按照格式,在下面写自己对应得zookeeper服务集群得ip
  • String connectString="192.168.106.43:2182,192.168.106.44:2182,192.168.106.45:2182";
  • // String connectString="192.168.106.43,192.168.106.44,192.168.106.45";
  • int sessionTimeout = 20000;
  • client = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
  • @Override
  • public void process(WatchedEvent watchedEvent) {
  • List<String> children = null;
  • try {
  • // 参数true表示开启子节点的监听
  • children = client.getChildren("/", true);
  • } catch (KeeperException e) {
  • e.printStackTrace();
  • } catch (InterruptedException e) {
  • e.printStackTrace();
  • }
  • for (String child: children) {
  • System.out.println(child);
  • }
  • }
  • });
  • }
  • }
  • @Test
  • public void grtChild() throws InterruptedException, KeeperException {
  • List<String> children = client.getChildren("/", true);
  • for (String child: children) {
  • System.out.println(child);
  • }
  • // 延时阻塞,防止程序退出
  • Thread.sleep(Long.MAX_VALUE);
  • }

二、判断节点是否存在

  • public class ZKClient {
  • ZooKeeper client;
  • @Before
  • public void init() throws IOException {
  • // 注意逗号后不要加空格,严格按照格式,在下面写自己对应得zookeeper服务集群得ip
  • String connectString="192.168.106.43:2182,192.168.106.44:2182,192.168.106.45:2182";
  • // String connectString="192.168.106.43,192.168.106.44,192.168.106.45";
  • int sessionTimeout = 20000;
  • client = new ZooKeeper(connectString, sessionTimeout, new Watcher() {
  • @Override
  • public void process(WatchedEvent watchedEvent) {}
  • });
  • }
  • @Test
  • public void exist() throws InterruptedException, KeeperException {
  • Stat exists = client.exists("/sanguo1", false);
  • System.out.println(exists==null?"not exist" : "exist");
  • }
  • }

三、zookeeper的写数据原理

不管是采用命令行还是api操作zookeeper集群,其实都是对于zookeeper进行写数据操作,那它的底层原理是什么呢?

(1)直接向leader发写请求

如上图。假设zookeeper集群中有三台zookeeper服务器,首先client会给leader写数据,然后leader给其中一个follower写数据,之后follower会回复leader。此时,集群已经有半数服务器更新了数据,会由leader向client回复。之后leader继续与其它的follow进行数据同步与回复确认。

(2)向follower发写请求

如上图。client给follower发送写请求后,follower会将请求转发给leader,leader进行写操作,并且选择一台follower完成写操作,follower响应请求并回复。当超过半数的服务器完成写操作后,会由leader回复给最开始响应client的follower,并由它对client进行回复。之后继续完成其它follower的数据同步与应答。

方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门