Zookeeper - API

ZooKeeper tiene un enlace API oficial para Java y C. La comunidad ZooKeeper proporciona API no oficial para la mayoría de los lenguajes (.NET, python, etc.). Usando la API de ZooKeeper, una aplicación puede conectarse, interactuar, manipular datos, coordinar y finalmente desconectarse de un conjunto de ZooKeeper.

La API de ZooKeeper tiene un rico conjunto de características para obtener toda la funcionalidad del conjunto ZooKeeper de una manera simple y segura. La API de ZooKeeper proporciona métodos sincrónicos y asincrónicos.

ZooKeeper ensemble y ZooKeeper API se complementan completamente en todos los aspectos y beneficia a los desarrolladores de una manera excelente. Analicemos el enlace de Java en este capítulo.

Conceptos básicos de la API de ZooKeeper

La aplicación que interactúa con el conjunto ZooKeeper se denomina ZooKeeper Client o simplemente Client.

Znode es el componente principal del conjunto ZooKeeper y la API de ZooKeeper proporciona un pequeño conjunto de métodos para manipular todos los detalles de znode con el conjunto ZooKeeper.

El cliente debe seguir los pasos que se indican a continuación para tener una interacción clara y limpia con el conjunto ZooKeeper.

  • Conéctese al conjunto ZooKeeper. El conjunto ZooKeeper asigna un ID de sesión para el cliente.

  • Envíe latidos al servidor periódicamente. De lo contrario, el conjunto ZooKeeper expira el ID de sesión y el cliente debe volver a conectarse.

  • Obtenga / configure los znodes siempre que haya una ID de sesión activa.

  • Desconéctese del conjunto ZooKeeper, una vez que haya completado todas las tareas. Si el cliente está inactivo durante un tiempo prolongado, el conjunto ZooKeeper desconectará automáticamente al cliente.

Enlace de Java

Comprendamos el conjunto más importante de API de ZooKeeper en este capítulo. La parte central de la API de ZooKeeper esZooKeeper class. Proporciona opciones para conectar el conjunto ZooKeeper en su constructor y tiene los siguientes métodos:

  • connect - conectarse al conjunto ZooKeeper

  • create - crear un znode

  • exists - comprobar si existe un znode y su información

  • getData - obtener datos de un znode en particular

  • setData - establecer datos en un znode particular

  • getChildren - obtener todos los subnodos disponibles en un znode particular

  • delete - obtener un znode particular y todos sus hijos

  • close - cerrar una conexión

Conéctese al conjunto ZooKeeper

La clase ZooKeeper proporciona funcionalidad de conexión a través de su constructor. La firma del constructor es la siguiente:

ZooKeeper(String connectionString, int sessionTimeout, Watcher watcher)

Dónde,

  • connectionString - Anfitrión del conjunto ZooKeeper.

  • sessionTimeout - tiempo de espera de la sesión en milisegundos.

  • watcher- un objeto que implementa la interfaz "Watcher". El conjunto ZooKeeper devuelve el estado de la conexión a través del objeto observador.

Creemos una nueva clase de ayuda ZooKeeperConnection y agrega un método connect. losconnect El método crea un objeto ZooKeeper, se conecta al conjunto ZooKeeper y luego devuelve el objeto.

aquí CountDownLatch se utiliza para detener (esperar) el proceso principal hasta que el cliente se conecta con el conjunto ZooKeeper.

El conjunto ZooKeeper responde el estado de la conexión a través del Watcher callback. La devolución de llamada de Watcher se llamará una vez que el cliente se conecte con el conjunto ZooKeeper y la devolución de llamada de Watcher llame alcountDown método del CountDownLatch para abrir la cerradura, await en el proceso principal.

Aquí está el código completo para conectarse con un conjunto de ZooKeeper.

Codificación: 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();
   }
}

Guarde el código anterior y se utilizará en la siguiente sección para conectar el conjunto ZooKeeper.

Crea un Znode

La clase ZooKeeper proporciona create methodpara crear un nuevo znode en el conjunto ZooKeeper. La firma delcreate El método es el siguiente:

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

Dónde,

  • path- Ruta de Znode. Por ejemplo, / myapp1, / ​​myapp2, / myapp1 / mydata1, myapp2 / mydata1 / myanothersubdata

  • data - datos para almacenar en una ruta de znode especificada

  • acl- lista de control de acceso del nodo a crear. La API de ZooKeeper proporciona una interfaz estáticaZooDefs.Idspara obtener algo de la lista básica de acl. Por ejemplo, ZooDefs.Ids.OPEN_ACL_UNSAFE devuelve una lista de acl para znodes abiertos.

  • createMode- el tipo de nodo, ya sea efímero, secuencial o ambos. Esto es unenum.

Creemos una nueva aplicación Java para comprobar el createfuncionalidad de la API de ZooKeeper. Crea un archivoZKCreate.java. En el método principal, crea un objeto de tipoZooKeeperConnection y llama al connect método para conectarse al conjunto ZooKeeper.

El método de conexión devolverá el objeto ZooKeeper zk. Ahora, llame alcreate método de zk objeto con personalizado path y data.

El código completo del programa para crear un znode es el siguiente:

Codificación: 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
      }
   }
}

Una vez compilada y ejecutada la aplicación, se creará un znode con los datos especificados en el conjunto de ZooKeeper. Puede verificarlo usando la CLI de ZooKeeperzkCli.sh.

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

Existe: compruebe la existencia de un Znode

La clase ZooKeeper proporciona la exists methodpara comprobar la existencia de un znode. Devuelve los metadatos de un znode, si existe el znode especificado. La firma delexists El método es el siguiente:

exists(String path, boolean watcher)

Dónde,

  • path - Ruta de Znode

  • watcher - valor booleano para especificar si se debe observar un znode especificado o no

Creemos una nueva aplicación Java para comprobar la funcionalidad "existente" de la API de ZooKeeper. Cree un archivo "ZKExists.java" . En el método principal, cree el objeto ZooKeeper, "zk" utilizando el objeto "ZooKeeperConnection" . Luego, llame al método "existe" del objeto "zk" con una "ruta" personalizada . La lista completa es la siguiente:

Codificación: 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
      }
   }
}

Una vez que la aplicación esté compilada y ejecutada, obtendrá el siguiente resultado.

Node exists and the node version is 1.

Método getData

La clase ZooKeeper proporciona getDatamétodo para obtener los datos adjuntos en un znode especificado y su estado. La firma delgetData El método es el siguiente:

getData(String path, Watcher watcher, Stat stat)

Dónde,

  • path - Ruta de Znode.

  • watcher - Función de devolución de llamada de tipo Watcher. El conjunto ZooKeeper notificará a través de la devolución de llamada de Watcher cuando cambien los datos del znode especificado. Esta es una notificación única.

  • stat - Devuelve los metadatos de un znode.

Creemos una nueva aplicación Java para comprender la getDatafuncionalidad de la API de ZooKeeper. Crea un archivoZKGetData.java. En el método principal, cree un objeto ZooKeeperzk usando él ZooKeeperConnectionobjeto. Entonces, llame algetData método de objeto zk con ruta personalizada.

Aquí está el código del programa completo para obtener los datos de un nodo específico:

Codificación: 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());
      }
   }
}

Una vez que la aplicación esté compilada y ejecutada, obtendrá el siguiente resultado

My first zookeeper app

Y la aplicación esperará nuevas notificaciones del conjunto ZooKeeper. Cambiar los datos del znode especificado usando ZooKeeper CLIzkCli.sh.

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

Ahora, la aplicación imprimirá la siguiente salida y saldrá.

Hello

Método setData

La clase ZooKeeper proporciona setDatamétodo para modificar los datos adjuntos en un znode especificado. La firma delsetData El método es el siguiente:

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

Dónde,

  • path - Ruta de Znode

  • data - datos para almacenar en una ruta de znode especificada.

  • version- Versión actual del znode. ZooKeeper actualiza el número de versión del znode cada vez que se modifican los datos.

Creemos ahora una nueva aplicación Java para comprender la setDatafuncionalidad de la API de ZooKeeper. Crea un archivoZKSetData.java. En el método principal, cree un objeto ZooKeeperzk utilizando el ZooKeeperConnectionobjeto. Entonces, llame alsetData método de zk objeto con la ruta especificada, nuevos datos y versión del nodo.

Aquí está el código del programa completo para modificar los datos adjuntos en un znode específico.

Código: 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());
      }
   }
}

Una vez que la aplicación se compila y ejecuta, los datos del znode especificado se cambiarán y se pueden verificar usando la CLI de ZooKeeper, zkCli.sh.

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

Método getChildren

La clase ZooKeeper proporciona getChildrenmétodo para obtener todos los subnodos de un znode en particular. La firma delgetChildren El método es el siguiente:

getChildren(String path, Watcher watcher)

Dónde,

  • path - Ruta de Znode.

  • watcher- Función de devolución de llamada de tipo "Watcher". El conjunto de ZooKeeper notificará cuando se elimine el znode especificado o cuando se cree / elimine un niño bajo el znode. Esta es una notificación única.

Codificación: 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());
      }

   }

}

Antes de ejecutar el programa, creemos dos subnodos para /MyFirstZnode utilizando la CLI de ZooKeeper, zkCli.sh.

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

Ahora, compilar y ejecutar el programa generará los znodes creados anteriormente.

myfirstsubnode
mysecondsubnode

Eliminar un Znode

La clase ZooKeeper proporciona deletemétodo para eliminar un znode especificado. La firma deldelete El método es el siguiente:

delete(String path, int version)

Dónde,

  • path - Ruta de Znode.

  • version - Versión actual del znode.

Creemos una nueva aplicación Java para comprender la deletefuncionalidad de la API de ZooKeeper. Crea un archivoZKDelete.java. En el método principal, cree un objeto ZooKeeperzk utilizando ZooKeeperConnectionobjeto. Entonces, llame aldelete método de zk objeto con el especificado path y versión del nodo.

El código de programa completo para eliminar un znode es el siguiente:

Codificación: 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
      }
   }
}