Zookeeper - API

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

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

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

Основы API ZooKeeper

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

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

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

  • Подключитесь к ансамблю ZooKeeper. Ансамбль ZooKeeper назначает идентификатор сеанса для клиента.

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

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

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

Java Binding

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

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

  • создать - создать узел

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

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

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

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

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

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

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

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

ZooKeeper(String connectionString, int sessionTimeout, Watcher watcher)

Где,

  • connectionString - хост ансамбля ZooKeeper.

  • sessionTimeout - время ожидания сеанса в миллисекундах.

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

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

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

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

Вот полный код для соединения с ансамблем 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 для создания нового znode в ансамбле ZooKeeper. Сигнатура метода создания выглядит следующим образом:

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

Где,

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

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

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

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

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

Метод connect возвращает объект ZooKeeper zk . Теперь вызовите метод create объекта zk с пользовательским путем и данными .

Полный программный код для создания 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 CLI zkCli.sh .

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

Exists - Проверьте существование Znode

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

exists(String path, boolean watcher)

Где,

  • путь - Znode путь

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

Давайте создадим новое Java-приложение для проверки «существующих» функциональных возможностей API ZooKeeper. Создайте файл «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)

Где,

  • путь - Зноде путь.

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

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

Давайте создадим новое приложение Java, чтобы понять функциональность getData API ZooKeeper. Создайте файл ZKGetData.java . В методе main создайте объект ZooKeeper zk, используя объект 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 CLI zkCli.sh .

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

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

Hello

Метод setData

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

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

Где,

  • путь - Znode путь

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

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

Теперь давайте создадим новое Java-приложение, чтобы понять функциональность setData API ZooKeeper. Создайте файл ZKSetData.java . В методе main создайте объект ZooKeeper zk, используя объект 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 для получения всех подузлов определенного узла. Подпись метода getChildren выглядит следующим образом:

getChildren(String path, Watcher watcher)

Где,

  • путь - Зноде путь.

  • watcher - функция обратного вызова типа «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(String path, int version)

Где,

  • путь - Зноде путь.

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

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

Полный код программы для удаления 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
      }
   }
}