Zookeeper - API

ZooKeeper имеет официальную привязку API для Java и C. Сообщество ZooKeeper предоставляет неофициальный API для большинства языков (.NET, python и т. Д.). Используя ZooKeeper API, приложение может подключаться, взаимодействовать, манипулировать данными, координировать и, наконец, отключаться от ансамбля ZooKeeper.

ZooKeeper API имеет богатый набор функций для простого и безопасного использования всех функций ансамбля ZooKeeper. ZooKeeper API предоставляет как синхронные, так и асинхронные методы.

Ансамбль ZooKeeper и ZooKeeper API полностью дополняют друг друга во всех аспектах, и это приносит большую пользу разработчикам. Давайте обсудим привязку Java в этой главе.

Основы ZooKeeper API

Приложение, взаимодействующее с ансамблем ZooKeeper, называется ZooKeeper Client или просто Client.

Znode является основным компонентом ансамбля ZooKeeper, а ZooKeeper API предоставляет небольшой набор методов для управления всеми деталями znode с помощью ансамбля ZooKeeper.

Клиент должен следовать приведенным ниже инструкциям, чтобы иметь четкое и чистое взаимодействие с ансамблем ZooKeeper.

  • Присоединяйтесь к ансамблю ZooKeeper. Ансамбль ZooKeeper присваивает клиенту идентификатор сеанса.

  • Периодически отправляйте контрольные сообщения на сервер. В противном случае у ансамбля ZooKeeper истекает срок действия идентификатора сеанса, и клиенту необходимо повторно подключиться.

  • Получить / установить znodes, пока активен идентификатор сеанса.

  • Отключитесь от ансамбля ZooKeeper, как только все задачи будут выполнены. Если клиент неактивен в течение длительного времени, ансамбль ZooKeeper автоматически отключит его.

Связывание Java

Давайте разберемся с наиболее важным набором ZooKeeper API в этой главе. Центральная часть ZooKeeper API - этоZooKeeper class. Он предоставляет параметры для подключения ансамбля ZooKeeper в своем конструкторе и имеет следующие методы:

  • connect - подключиться к ансамблю ZooKeeper

  • create - создать znode

  • exists - проверить, существует ли znode и его информацию

  • getData - получить данные из определенного znode

  • setData - установить данные в определенном узле

  • getChildren - получить все подузлы, доступные в конкретном znode

  • delete - получить конкретный znode и всех его потомков

  • close - закрыть соединение

Подключитесь к ансамблю ZooKeeper

Класс ZooKeeper предоставляет функциональные возможности подключения через свой конструктор. Подпись конструктора следующая -

ZooKeeper(String connectionString, int sessionTimeout, Watcher watcher)

Где,

  • connectionString - Ведущий ансамбля ZooKeeper.

  • sessionTimeout - тайм-аут сеанса в миллисекундах.

  • watcher- объект, реализующий интерфейс «Наблюдатель». Ансамбль ZooKeeper возвращает статус соединения через объект-наблюдатель.

Давайте создадим новый вспомогательный класс ZooKeeperConnection и добавить метод connect. Вconnect создает объект ZooKeeper, подключается к ансамблю ZooKeeper, а затем возвращает объект.

Вот CountDownLatch используется для остановки (ожидания) основного процесса, пока клиент не подключится к ансамблю ZooKeeper.

Ансамбль ZooKeeper отвечает на статус подключения через Watcher callback. Обратный вызов Watcher будет вызываться, когда клиент подключится к ансамблю ZooKeeper, а обратный вызов Watcher вызываетcountDown метод CountDownLatch снять блокировку, await в основном процессе.

Вот полный код для подключения к ансамблю ZooKeeper.

Кодирование: ZooKeeperConnection.java

// import java classes
import java.io.IOException;
import java.util.concurrent.CountDownLatch;

// import zookeeper classes
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.AsyncCallback.StatCallback;
import org.apache.zookeeper.KeeperException.Code;
import org.apache.zookeeper.data.Stat;

public class ZooKeeperConnection {

   // declare zookeeper instance to access ZooKeeper ensemble
   private ZooKeeper zoo;
   final CountDownLatch connectedSignal = new CountDownLatch(1);

   // Method to connect zookeeper ensemble.
   public ZooKeeper connect(String host) throws IOException,InterruptedException {
	
      zoo = new ZooKeeper(host,5000,new Watcher() {
		
         public void process(WatchedEvent we) {

            if (we.getState() == KeeperState.SyncConnected) {
               connectedSignal.countDown();
            }
         }
      });
		
      connectedSignal.await();
      return zoo;
   }

   // Method to disconnect from zookeeper server
   public void close() throws InterruptedException {
      zoo.close();
   }
}

Сохраните приведенный выше код, и он будет использован в следующем разделе для подключения ансамбля ZooKeeper.

Создать Znode

Класс ZooKeeper предоставляет create methodдля создания нового znode в ансамбле ZooKeeper. Подписьcreate метод выглядит следующим образом -

create(String path, byte[] data, List<ACL> acl, CreateMode createMode)

Где,

  • path- Знодейский путь. Например, / myapp1, / ​​myapp2, / myapp1 / mydata1, myapp2 / mydata1 / myanothersubdata

  • data - данные для хранения по указанному пути znode

  • acl- список контроля доступа создаваемого узла. ZooKeeper API предоставляет статический интерфейсZooDefs.Idsчтобы получить базовый список ACL. Например, ZooDefs.Ids.OPEN_ACL_UNSAFE возвращает список acl для открытых znodes.

  • createMode- тип узла: эфемерный, последовательный или и то, и другое. Этоenum.

Давайте создадим новое приложение Java, чтобы проверить createфункциональность ZooKeeper API. Создать файлZKCreate.java. В основном методе создайте объект типаZooKeeperConnection и позвонить в connect способ подключения к ансамблю ZooKeeper.

Метод подключения вернет объект ZooKeeper zk. Теперь позвоните вcreate метод zk объект с индивидуальным path и data.

Полный программный код для создания znode выглядит следующим образом:

Кодирование: ZKCreate.java

import java.io.IOException;

import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;

public class ZKCreate {
   // create static instance for zookeeper class.
   private static ZooKeeper zk;

   // create static instance for ZooKeeperConnection class.
   private static ZooKeeperConnection conn;

   // Method to create znode in zookeeper ensemble
   public static void create(String path, byte[] data) throws 
      KeeperException,InterruptedException {
      zk.create(path, data, ZooDefs.Ids.OPEN_ACL_UNSAFE,
      CreateMode.PERSISTENT);
   }

   public static void main(String[] args) {

      // znode path
      String path = "/MyFirstZnode"; // Assign path to znode

      // data in byte array
      byte[] data = "My first zookeeper app”.getBytes(); // Declare data
		
      try {
         conn = new ZooKeeperConnection();
         zk = conn.connect("localhost");
         create(path, data); // Create the data to the specified path
         conn.close();
      } catch (Exception e) {
         System.out.println(e.getMessage()); //Catch error message
      }
   }
}

После того, как приложение скомпилировано и выполнено, в ансамбле ZooKeeper будет создан znode с указанными данными. Вы можете проверить это с помощью ZooKeeper CLIzkCli.sh.

cd /path/to/zookeeper
bin/zkCli.sh
>>> get /MyFirstZnode

Exists - проверьте наличие Znode

Класс ZooKeeper предоставляет exists methodчтобы проверить наличие znode. Он возвращает метаданные znode, если указанный znode существует. Подписьexists метод выглядит следующим образом -

exists(String path, boolean watcher)

Где,

  • path - Знодейский путь

  • watcher - логическое значение, чтобы указать, смотреть ли указанный znode или нет

Давайте создадим новое приложение Java, чтобы проверить «существует» функциональность ZooKeeper API. Создайте файл «ZKExists.java» . В основном методе создайте объект ZooKeeper, «zk», используя объект «ZooKeeperConnection» . Затем вызовите метод «существует» объекта «zk» с настраиваемым «путем» . Полный список выглядит следующим образом -

Кодирование: ZKExists.java

import java.io.IOException;

import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.data.Stat;

public class ZKExists {
   private static ZooKeeper zk;
   private static ZooKeeperConnection conn;

   // Method to check existence of znode and its status, if znode is available.
   public static Stat znode_exists(String path) throws
      KeeperException,InterruptedException {
      return zk.exists(path, true);
   }

   public static void main(String[] args) throws InterruptedException,KeeperException {
      String path = "/MyFirstZnode"; // Assign znode to the specified path
			
      try {
         conn = new ZooKeeperConnection();
         zk = conn.connect("localhost");
         Stat stat = znode_exists(path); // Stat checks the path of the znode
				
         if(stat != null) {
            System.out.println("Node exists and the node version is " +
            stat.getVersion());
         } else {
            System.out.println("Node does not exists");
         }
				
      } catch(Exception e) {
         System.out.println(e.getMessage()); // Catches error messages
      }
   }
}

После того, как приложение скомпилировано и выполнено, вы получите следующий результат.

Node exists and the node version is 1.

getData Метод

Класс ZooKeeper предоставляет getDataдля получения данных, вложенных в указанный znode, и его статуса. ПодписьgetData метод выглядит следующим образом -

getData(String path, Watcher watcher, Stat stat)

Где,

  • path - Знодейский путь.

  • watcher - Функция обратного вызова типа Watcher. Ансамбль ZooKeeper будет уведомлять через обратный вызов Watcher, когда данные указанного znode изменяются. Это разовое уведомление.

  • stat - Возвращает метаданные znode.

Давайте создадим новое приложение Java, чтобы понять getDataфункциональность ZooKeeper API. Создать файлZKGetData.java. В основном методе создайте объект ZooKeeperzk используя он ZooKeeperConnectionобъект. Затем позвоните вgetData метод объекта zk с настраиваемым путем.

Вот полный программный код для получения данных из указанного узла:

Кодирование: ZKGetData.java

import java.io.IOException;
import java.util.concurrent.CountDownLatch;

import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.data.Stat;

public class ZKGetData {

   private static ZooKeeper zk;
   private static ZooKeeperConnection conn;
   public static Stat znode_exists(String path) throws 
      KeeperException,InterruptedException {
      return zk.exists(path,true);
   }

   public static void main(String[] args) throws InterruptedException, KeeperException {
      String path = "/MyFirstZnode";
      final CountDownLatch connectedSignal = new CountDownLatch(1);
		
      try {
         conn = new ZooKeeperConnection();
         zk = conn.connect("localhost");
         Stat stat = znode_exists(path);
			
         if(stat != null) {
            byte[] b = zk.getData(path, new Watcher() {
				
               public void process(WatchedEvent we) {
					
                  if (we.getType() == Event.EventType.None) {
                     switch(we.getState()) {
                        case Expired:
                        connectedSignal.countDown();
                        break;
                     }
							
                  } else {
                     String path = "/MyFirstZnode";
							
                     try {
                        byte[] bn = zk.getData(path,
                        false, null);
                        String data = new String(bn,
                        "UTF-8");
                        System.out.println(data);
                        connectedSignal.countDown();
							
                     } catch(Exception ex) {
                        System.out.println(ex.getMessage());
                     }
                  }
               }
            }, null);
				
            String data = new String(b, "UTF-8");
            System.out.println(data);
            connectedSignal.await();
				
         } else {
            System.out.println("Node does not exists");
         }
      } catch(Exception e) {
        System.out.println(e.getMessage());
      }
   }
}

Когда приложение скомпилировано и выполнено, вы получите следующий результат

My first zookeeper app

И приложение будет ждать дальнейшего уведомления от ансамбля ZooKeeper. Измените данные указанного znode с помощью ZooKeeper CLIzkCli.sh.

cd /path/to/zookeeper
bin/zkCli.sh
>>> set /MyFirstZnode Hello

Теперь приложение напечатает следующий вывод и завершит работу.

Hello

setData Метод

Класс ZooKeeper предоставляет setDataдля изменения данных, вложенных в указанный znode. ПодписьsetData метод выглядит следующим образом -

setData(String path, byte[] data, int version)

Где,

  • path - Знодейский путь

  • data - данные для хранения по указанному пути znode.

  • version- Текущая версия znode. ZooKeeper обновляет номер версии znode при изменении данных.

Давайте теперь создадим новое приложение Java, чтобы понять setDataфункциональность ZooKeeper API. Создать файлZKSetData.java. В основном методе создайте объект ZooKeeperzk используя ZooKeeperConnectionобъект. Затем позвоните вsetData метод zk объект с указанным путем, новыми данными и версией узла.

Вот полный программный код для изменения данных, прикрепленных в указанном znode.

Код: ZKSetData.java

import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.KeeperState;

import java.io.IOException;

public class ZKSetData {
   private static ZooKeeper zk;
   private static ZooKeeperConnection conn;

   // Method to update the data in a znode. Similar to getData but without watcher.
   public static void update(String path, byte[] data) throws
      KeeperException,InterruptedException {
      zk.setData(path, data, zk.exists(path,true).getVersion());
   }

   public static void main(String[] args) throws InterruptedException,KeeperException {
      String path= "/MyFirstZnode";
      byte[] data = "Success".getBytes(); //Assign data which is to be updated.
		
      try {
         conn = new ZooKeeperConnection();
         zk = conn.connect("localhost");
         update(path, data); // Update znode data to the specified path
      } catch(Exception e) {
         System.out.println(e.getMessage());
      }
   }
}

После того, как приложение скомпилировано и выполнено, данные указанного znode будут изменены, и их можно будет проверить с помощью ZooKeeper CLI, zkCli.sh.

cd /path/to/zookeeper
bin/zkCli.sh
>>> get /MyFirstZnode

getChildren Метод

Класс ZooKeeper предоставляет getChildrenдля получения всех подузлов конкретного znode. ПодписьgetChildren метод выглядит следующим образом -

getChildren(String path, Watcher watcher)

Где,

  • path - Знодейский путь.

  • watcher- Функция обратного вызова типа «Наблюдатель». Ансамбль ZooKeeper будет уведомлять, когда указанный znode будет удален или дочерний элемент под znode будет создан / удален. Это разовое уведомление.

Кодирование: ZKGetChildren.java

import java.io.IOException;
import java.util.*;

import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.data.Stat;

public class ZKGetChildren {
   private static ZooKeeper zk;
   private static ZooKeeperConnection conn;

   // Method to check existence of znode and its status, if znode is available.
   public static Stat znode_exists(String path) throws 
      KeeperException,InterruptedException {
      return zk.exists(path,true);
   }

   public static void main(String[] args) throws InterruptedException,KeeperException {
      String path = "/MyFirstZnode"; // Assign path to the znode
		
      try {
         conn = new ZooKeeperConnection();
         zk = conn.connect("localhost");
         Stat stat = znode_exists(path); // Stat checks the path

         if(stat!= null) {

            //“getChildren” method- get all the children of znode.It has two
            args, path and watch
            List <String> children = zk.getChildren(path, false);
            for(int i = 0; i < children.size(); i++)
            System.out.println(children.get(i)); //Print children's
         } else {
            System.out.println("Node does not exists");
         }

      } catch(Exception e) {
         System.out.println(e.getMessage());
      }

   }

}

Перед запуском программы создадим два подузла для /MyFirstZnode используя ZooKeeper CLI, zkCli.sh.

cd /path/to/zookeeper
bin/zkCli.sh
>>> create /MyFirstZnode/myfirstsubnode Hi
>>> create /MyFirstZnode/mysecondsubmode Hi

Теперь при компиляции и запуске программы будут выведены созданные выше znodes.

myfirstsubnode
mysecondsubnode

Удалить Znode

Класс ZooKeeper предоставляет deleteметод удаления указанного znode. Подписьdelete метод выглядит следующим образом -

delete(String path, int version)

Где,

  • path - Знодейский путь.

  • version - Текущая версия znode.

Давайте создадим новое приложение Java, чтобы понять deleteфункциональность ZooKeeper API. Создать файлZKDelete.java. В основном методе создайте объект ZooKeeperzk с помощью ZooKeeperConnectionобъект. Затем позвоните вdelete метод zk объект с указанным path и версия узла.

Полный программный код для удаления znode выглядит следующим образом:

Кодирование: ZKDelete.java

import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.KeeperException;

public class ZKDelete {
   private static ZooKeeper zk;
   private static ZooKeeperConnection conn;

   // Method to check existence of znode and its status, if znode is available.
   public static void delete(String path) throws KeeperException,InterruptedException {
      zk.delete(path,zk.exists(path,true).getVersion());
   }

   public static void main(String[] args) throws InterruptedException,KeeperException {
      String path = "/MyFirstZnode"; //Assign path to the znode
		
      try {
         conn = new ZooKeeperConnection();
         zk = conn.connect("localhost");
         delete(path); //delete the node with the specified path
      } catch(Exception e) {
         System.out.println(e.getMessage()); // catches error messages
      }
   }
}