Zookeeper - API

ZooKeeper ha un'associazione API ufficiale per Java e C. La comunità ZooKeeper fornisce API non ufficiali per la maggior parte dei linguaggi (.NET, python, ecc.). Utilizzando l'API ZooKeeper, un'applicazione può connettersi, interagire, manipolare dati, coordinare e infine disconnettersi da un insieme ZooKeeper.

L'API ZooKeeper ha un ricco set di funzionalità per ottenere tutte le funzionalità dell'insieme ZooKeeper in modo semplice e sicuro. L'API di ZooKeeper fornisce metodi sia sincroni che asincroni.

L'insieme ZooKeeper e l'API ZooKeeper si completano a vicenda in ogni aspetto e avvantaggiano gli sviluppatori in modo eccezionale. Parliamo dell'associazione Java in questo capitolo.

Nozioni di base sull'API ZooKeeper

L'applicazione che interagisce con l'insieme ZooKeeper viene chiamata ZooKeeper Client o semplicemente Client.

Znode è il componente principale dell'ensemble ZooKeeper e l'API ZooKeeper fornisce un piccolo insieme di metodi per manipolare tutti i dettagli di znode con l'ensemble ZooKeeper.

Un cliente deve seguire i passaggi indicati di seguito per avere un'interazione chiara e pulita con l'insieme ZooKeeper.

  • Connettiti all'ensemble ZooKeeper. L'insieme ZooKeeper assegna un ID sessione per il client.

  • Invia periodicamente heartbeat al server. In caso contrario, l'insieme ZooKeeper fa scadere l'ID sessione e il client deve riconnettersi.

  • Ottieni / imposta gli znodes fintanto che l'ID di sessione è attivo.

  • Disconnettiti dall'insieme ZooKeeper, una volta completate tutte le attività. Se il client è inattivo per un periodo di tempo prolungato, l'insieme ZooKeeper disconnetterà automaticamente il client.

Associazione Java

Comprendiamo il set più importante di API ZooKeeper in questo capitolo. La parte centrale dell'API ZooKeeper èZooKeeper class. Fornisce opzioni per connettere l'insieme ZooKeeper nel suo costruttore e ha i seguenti metodi:

  • connect - connettersi all'ensemble ZooKeeper

  • create - crea uno znode

  • exists - controlla se esiste uno znode e le sue informazioni

  • getData - ottenere dati da un particolare znode

  • setData - imposta i dati in un particolare znode

  • getChildren - ottieni tutti i sotto-nodi disponibili in un particolare znode

  • delete - prendi un particolare znode e tutti i suoi figli

  • close - chiudere una connessione

Connettiti allo ZooKeeper Ensemble

La classe ZooKeeper fornisce funzionalità di connessione tramite il suo costruttore. La firma del costruttore è la seguente:

ZooKeeper(String connectionString, int sessionTimeout, Watcher watcher)

Dove,

  • connectionString - Host dell'ensemble ZooKeeper.

  • sessionTimeout - timeout della sessione in millisecondi.

  • watcher- un oggetto che implementa l'interfaccia "Watcher". L'insieme ZooKeeper restituisce lo stato della connessione tramite l'oggetto watcher.

Creiamo una nuova classe helper ZooKeeperConnection e aggiungi un metodo connect. Ilconnect crea un oggetto ZooKeeper, si connette all'ensemble ZooKeeper e quindi restituisce l'oggetto.

Qui CountDownLatch viene utilizzato per interrompere (attendere) il processo principale fino a quando il client si connette con l'insieme ZooKeeper.

L'insieme ZooKeeper risponde dello stato della connessione tramite Watcher callback. La richiamata Watcher verrà chiamata una volta che il client si connette con l'insieme ZooKeeper e la richiamata Watcher chiamerà il filecountDown metodo del CountDownLatch per rilasciare la serratura, await nel processo principale.

Ecco il codice completo per connettersi con un insieme ZooKeeper.

Codifica: 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();
   }
}

Salva il codice sopra e verrà utilizzato nella sezione successiva per collegare l'insieme ZooKeeper.

Crea uno Znode

La classe ZooKeeper fornisce create methodper creare un nuovo znode nell'insieme ZooKeeper. La firma delcreate metodo è il seguente:

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

Dove,

  • path- Percorso Znode. Ad esempio, / myapp1, / ​​myapp2, / myapp1 / mydata1, myapp2 / mydata1 / myanothersubdata

  • data - dati da memorizzare in un percorso znode specificato

  • acl- lista di controllo accessi del nodo da creare. L'API ZooKeeper fornisce un'interfaccia staticaZooDefs.Idsper ottenere alcune delle liste ACL di base. Ad esempio, ZooDefs.Ids.OPEN_ACL_UNSAFE restituisce un elenco di acl per gli znodi aperti.

  • createMode- il tipo di nodo, effimero, sequenziale o entrambi. Questo è unenum.

Creiamo una nuova applicazione Java per controllare il file createfunzionalità dell'API ZooKeeper. Crea un fileZKCreate.java. Nel metodo principale, crea un oggetto di tipoZooKeeperConnection e chiama il connect metodo per connettersi all'ensemble ZooKeeper.

Il metodo connect restituirà l'oggetto ZooKeeper zk. Ora, chiama ilcreate metodo di zk oggetto con custom path e data.

Il codice completo del programma per creare uno znode è il seguente:

Codifica: 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 volta che l'applicazione è stata compilata ed eseguita, verrà creato uno znode con i dati specificati nell'insieme ZooKeeper. Puoi verificarlo utilizzando la CLI di ZooKeeperzkCli.sh.

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

Esiste: controlla l'esistenza di uno Znode

La classe ZooKeeper fornisce l'estensione exists methodper verificare l'esistenza di uno znode. Restituisce i metadati di uno znode, se lo znode specificato esiste. La firma delexists metodo è il seguente:

exists(String path, boolean watcher)

Dove,

  • path - Percorso Znode

  • watcher - valore booleano per specificare se guardare o meno uno znode specificato

Creiamo una nuova applicazione Java per verificare la funzionalità "esistente" dell'API ZooKeeper. Crea un file "ZKExists.java" . Nel metodo principale, creare l'oggetto ZooKeeper, "zk" utilizzando l' oggetto "ZooKeeperConnection" . Quindi, chiama il metodo "esiste " dell'oggetto "zk" con "percorso" personalizzato . L'elenco completo è il seguente:

Codifica: 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 volta che l'applicazione è stata compilata ed eseguita, otterrai l'output seguente.

Node exists and the node version is 1.

Metodo getData

La classe ZooKeeper fornisce getDatametodo per ottenere i dati allegati in uno znode specificato e il suo stato. La firma delgetData metodo è il seguente:

getData(String path, Watcher watcher, Stat stat)

Dove,

  • path - Percorso Znode.

  • watcher - Funzione di richiamata di tipo Watcher. L'ensemble ZooKeeper notificherà tramite il callback Watcher quando i dati dello znode specificato cambiano. Questa è una notifica una tantum.

  • stat - Restituisce i metadati di uno znode.

Creiamo una nuova applicazione Java per comprendere il getDatafunzionalità dell'API ZooKeeper. Crea un fileZKGetData.java. Nel metodo principale, crea un oggetto ZooKeeperzk usando lui ZooKeeperConnectionoggetto. Quindi, chiama ilgetData metodo dell'oggetto zk con percorso personalizzato.

Ecco il codice completo del programma per ottenere i dati da un nodo specificato -

Codifica: 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 volta che l'applicazione è stata compilata ed eseguita, otterrai il seguente output

My first zookeeper app

E l'applicazione attenderà ulteriori notifiche dall'insieme ZooKeeper. Modificare i dati dello znode specificato utilizzando la CLI di ZooKeeperzkCli.sh.

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

Ora l'applicazione stamperà il seguente output e uscirà.

Hello

metodo setData

La classe ZooKeeper fornisce setDatametodo per modificare i dati allegati in uno znode specificato. La firma delsetData metodo è il seguente:

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

Dove,

  • path - Percorso Znode

  • data - dati da memorizzare in un percorso znode specificato.

  • version- Versione corrente di znode. ZooKeeper aggiorna il numero di versione di znode ogni volta che i dati vengono modificati.

Creiamo ora una nuova applicazione Java per comprendere il file setDatafunzionalità dell'API ZooKeeper. Crea un fileZKSetData.java. Nel metodo principale, crea un oggetto ZooKeeperzk usando il ZooKeeperConnectionoggetto. Quindi, chiama ilsetData metodo di zk oggetto con il percorso specificato, i nuovi dati e la versione del nodo.

Ecco il codice completo del programma per modificare i dati allegati in uno znode specificato.

Codice: 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 volta che l'applicazione è stata compilata ed eseguita, i dati dello znode specificato verranno modificati e potranno essere controllati utilizzando la CLI di ZooKeeper, zkCli.sh.

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

Metodo getChildren

La classe ZooKeeper fornisce getChildrenmetodo per ottenere tutti i sottonodi di un particolare znode. La firma delgetChildren metodo è il seguente:

getChildren(String path, Watcher watcher)

Dove,

  • path - Percorso Znode.

  • watcher- Funzione di richiamata di tipo "Watcher". L'ensemble ZooKeeper notificherà quando lo znode specificato viene eliminato o un figlio sotto lo znode viene creato / eliminato. Questa è una notifica una tantum.

Codifica: 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());
      }

   }

}

Prima di eseguire il programma, creiamo due sottonodi per /MyFirstZnode utilizzando la CLI di ZooKeeper, zkCli.sh.

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

Ora, la compilazione e l'esecuzione del programma produrrà gli znodes creati sopra.

myfirstsubnode
mysecondsubnode

Elimina uno Znode

La classe ZooKeeper fornisce deletemetodo per eliminare uno znode specificato. La firma deldelete metodo è il seguente:

delete(String path, int version)

Dove,

  • path - Percorso Znode.

  • version - Versione corrente di znode.

Creiamo una nuova applicazione Java per comprendere il deletefunzionalità dell'API ZooKeeper. Crea un fileZKDelete.java. Nel metodo principale, crea un oggetto ZooKeeperzk utilizzando ZooKeeperConnectionoggetto. Quindi, chiama ildelete metodo di zk oggetto con il file path e la versione del nodo.

Il codice completo del programma per eliminare uno znode è il seguente:

Codifica: 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
      }
   }
}