Heim  >  Artikel  >  Java  >  Verwendung von ZooKeeper für die verteilte Koordination in der Java-API-Entwicklung

Verwendung von ZooKeeper für die verteilte Koordination in der Java-API-Entwicklung

PHPz
PHPzOriginal
2023-06-17 22:37:441877Durchsuche

Mit der kontinuierlichen Verbesserung der Leistung von Computersystemen und der kontinuierlichen Reduzierung der Hardwarekosten werden verteilte Systeme im Bereich der modernen Datenverarbeitung immer wichtiger. Damit einhergehend wächst die Nachfrage nach verteiltem Computing weiter und die Koordinations- und Managementlösungen für verteilte Systeme gewinnen immer mehr an Bedeutung.

Es gibt viele Lösungen, um eine verteilte Koordination zu erreichen, und ZooKeeper ist eine der beliebtesten Lösungen. ZooKeeper ist eines der Unterprojekte des Apache Hadoop-Projekts. Es bietet einen zuverlässigen verteilten Koordinationsdienst, der es Anwendungsentwicklern erleichtert, verteilte Systeme zu implementieren.

Die Verwendung von ZooKeeper für die verteilte Koordination in der Java-API-Entwicklung ist zu einem heißen Thema geworden. In diesem Artikel werden einige grundlegende Konzepte von ZooKeeper untersucht und praktische Beispiele bereitgestellt, um zu veranschaulichen, wie ZooKeeper für die verteilte Koordination in Java verwendet wird.

Einführung in ZooKeeper

ZooKeeper ist ein verteilter Dienst zur Koordinierung verteilter Anwendungen. Das Hauptziel von ZooKeeper besteht darin, Entwicklern einen relativ einfachen Koordinationsdienst zur Verfügung zu stellen, damit sie sich auf das Schreiben von Anwendungen konzentrieren können.

ZooKeeper verfügt über die folgenden Funktionen:

  • ZooKeeper ist ein verteilter Dienst, der über mehrere Knoten bereitgestellt werden kann, um eine hohe Verfügbarkeit zu gewährleisten.
  • ZooKeeper ist als Architektur mit einem Masterknoten und mehreren Slaveknoten konzipiert. In dieser Struktur ist der Master-Knoten für die Koordination und Verwaltung der Slave-Knoten verantwortlich und sorgt dafür, dass die Daten sicher gespeichert werden.
  • ZooKeeper verfolgt den Status und die Änderungen von Knoten mithilfe von „ZooKeeper Temporary Ordered Nodes“. Bei diesen Knoten handelt es sich um einen besonderen Knotentyp, der eine einmalige Verbindung zwischen seinem Ersteller und dem ZooKeeper-Dienst herstellt. Bei einem Verbindungsabbruch wird der Knoten gelöscht und so sichergestellt, dass der Knotenstatus zeitnah aktualisiert wird.
  • ZooKeeper kann die Konsistenz und Integrität von Daten mithilfe der Versionskontrollfunktion verwalten. Bei Verwendung der Versionskontrolle erhöht ZooKeeper die Versionsnummer jedes Knotens.

Grundlegende Vorgänge von ZooKeeper

Bei der Verwendung von ZooKeeper für die verteilte Koordination sind die am häufigsten verwendeten Vorgänge das Erstellen von Knoten, das Lesen von Knoten und die Überwachung des Knotenstatus.

Knoten erstellen

Um einen Knoten zu erstellen, müssen Sie den Knotenpfad und die Knotendaten angeben. Der Knoten wird dem ZooKeeper-Dienst als Unterverzeichnis hinzugefügt. Wenn es sich bei dem erstellten Knoten um einen kurzlebigen Knoten handelt, kann auf ihn nur zugegriffen werden, solange die Verbindung zwischen dem Client, der ihn erstellt hat, und dem ZooKeeper-Dienst gültig ist.

Das Folgende ist Beispielcode zum Erstellen eines Knotens mithilfe der ZooKeeper-API:

ZooKeeper zk = new ZooKeeper("localhost:2181", 3000, null);
String nodePath = "/testNode";
byte[] data = "nodeData".getBytes();
CreateMode createMode = CreateMode.EPHEMERAL;
zk.create(nodePath, data, ZooDefs.Ids.OPEN_ACL_UNSAFE, createMode);

Einen Knoten lesen

Sie können den Inhalt eines Knotens mithilfe der ZooKeeper-API lesen und abrufen. Das Folgende ist ein Beispielcode zum Lesen von Knoten mithilfe der Java-API:

ZooKeeper zk = new ZooKeeper("localhost:2181", 3000, null);
String nodePath = "/testNode";
byte[] data = zk.getData(nodePath, false, null);

Knoten überwachen

Knoten überwachen ermöglicht es dem Client, über Knotenänderungen benachrichtigt zu werden, sodass der Knotenstatus aktualisiert werden kann. Das Folgende ist ein Beispielcode für die Überwachung von Knoten mithilfe der ZooKeeper-API:

ZooKeeper zk = new ZooKeeper("localhost:2181", 3000, null);
String nodePath = "/testNode";
Watcher watcher = new Watcher() {
   public void process(WatchedEvent event) {
      // do something
   }
};
byte[] data = zk.getData(nodePath, watcher, null);

Beispiel für verteilte Koordination mit ZooKeeper

Im folgenden Beispiel implementieren wir eine einfache verteilte Anwendung mithilfe der ZooKeeper-API, die ein einfaches A-Leader-Wahlprotokoll implementiert Mehrere Prozesse konkurrieren um die Führung. In diesem Fall verwenden wir kurzlebige ZooKeeper-Knoten, um die Funktion zur Wahl des Anführers zu implementieren.

Hier ist der Beispielcode:

import java.util.List;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.KeeperException.NodeExistsException;
import org.apache.zookeeper.data.Stat;
 
public class LeaderElection implements Watcher {
    
   String znode = "/leader_election";    

   ZooKeeper zk;
   String serverId = Integer.toHexString((int)(Math.random() * 1000000));
    
   boolean isLeader = false;
    
   public void start() throws Exception{
       
      String serverPath = znode + "/" + serverId;
 
      zk = new ZooKeeper("localhost:2181", 3000, this); 

      while(zk.getState() == ZooKeeper.States.CONNECTING){
         
         Thread.sleep(500); 

      }
       
      while(true){
          
        try{
        
            // create the node with EPHEMERAL and SEQUENTIAL flags
            
            zk.create(serverPath, null, ZooDefs.Ids.OPEN_ACL_UNSAFE,
              CreateMode.EPHEMERAL);
          
            isLeader = true; 

            doLeaderAction();
            break;

         } catch (NodeExistsException e){
                
            isLeader = false;
            break; 

         } catch (InterruptedException e) {
             
             throw e;
             
         } catch (Exception e) {
             
             throw new RuntimeException(e); 
             
         }
      }
   }
    
   public void stop() throws Exception{
       
      zk.close(); 
       
   }
   
   void doLeaderAction() throws Exception {
       
      System.out.println("Becoming leader: " + serverId);
       
      try {            
               
         Thread.sleep(6000);
               
      } catch (InterruptedException e) {

         System.err.println("Interrupted while " +
               "sleeping during leadership.");
         
         Thread.currentThread().interrupt();
      } finally {

         try {               
            System.out.println("Ending leader: " + serverId);
         } catch (Exception e) {
            System.err.println("Error ending leadership."); 
         }
      }
   }
    
   public void process(WatchedEvent e){
       
      System.out.println(e.toString() + ", " + serverId);
      try {
        electLeader();
      } catch (Exception ex) {
        ex.printStackTrace();
      }   
   }
    
   void electLeader() throws Exception {
       
      Stat predecessorStat = null;
      String predecessor = null;
      
      List<String> children = zk.getChildren(znode, false); //(watcher not needed for this operation)
      
      int currentId = Integer.parseInt(serverId, 16); 
       
      for(String child : children){
          
        int childId = Integer.parseInt(child, 16);
        
        if(childId < currentId) {
            
            if(predecessorStat == null){
                
                predecessor = child; 
                predecessorStat = zk.exists(znode + "/" + child, true); 

            } else {
                
                Stat stat = zk.exists(znode + "/" + child, true);
              
                if(stat.getMzxid() < predecessorStat.getMzxid()){
                    
                    predecessor = child; 
                    predecessorStat = stat; 
                }               
            }
        }

      }
       
      if(predecessor == null){
           
        System.out.println("No active group members, " + serverId + " as leader.");
        //...provisional leader code here
           
      } else{ // watch the predecessor node waiting for it to go
                // ...down or to receive a message that it is was elected leader too.        
        System.out.println("Watching group member with higher ID: " + predecessor);
      }         
   }
   
   public static void main(String[] args) throws Exception {
          
      LeaderElection election = new LeaderElection();
      
      election.start();
       
   }
}

Im obigen Beispielcode erstellen wir zunächst ein Znode-Unterverzeichnis, das verwendet wird, um den Teilnahmestatus aller an der Leiterwahl beteiligten Prozesse aufrechtzuerhalten. Als Nächstes erstellen wir einen temporären geordneten ZooKeeper-Knoten, der einen bestimmten Akteur darstellt. Wie bereits erwähnt, stellt ZooKeeper eine einmalige Verbindung zwischen dem Client und dem Zk-Wert her. Nachdem wir diesen temporären Knoten erstellt haben und die Clientverbindung verloren geht, wird der Knoten gelöscht. Wenn ein Prozess beim Einrichten eines Knotens feststellt, dass bereits ein Knoten mit demselben Knotennamen vorhanden ist, wird der Prozess nicht zum Anführer.

Wenn der Client den temporären Knoten erfolgreich erstellt, wird der Client zum Leiter. Hier können wir die Methode doLeaderAction() aufrufen, die die Aktion darstellt, die der Anführer ausführen wird. In diesem Beispiel führt der Leiter einen einfachen 6-Sekunden-Vorgang aus.

Wenn die Client-Verbindung unterbrochen wurde oder ein Fehler auftritt, überprüft der Prozess die Knoten im vorhandenen Verzeichnis, um festzustellen, welcher Knoten der neue Anführer wird.

Fazit

Verteilte Koordination und Verwaltung ist eines der wichtigsten Themen im Bereich der modernen Datenverarbeitung, und die Anwendung verteilter Systeme erfreut sich immer größerer Beliebtheit. ZooKeeper ist eine beliebte Lösung, die Entwicklern die Implementierung verteilter Systeme erleichtert. In der Java-API-Entwicklung umfassen die Hauptvorgänge bei der Verwendung von ZooKeeper für die verteilte Koordination das Erstellen von Knoten, das Lesen von Knoten und die Überwachung des Knotenstatus. Anhand des Beispielcodes in diesem Artikel können Sie sehen, wie Sie ZooKeeper verwenden, um das Leader-Wahlprotokoll und andere verteilte Koordinationsschemata in Java zu implementieren.

Das obige ist der detaillierte Inhalt vonVerwendung von ZooKeeper für die verteilte Koordination in der Java-API-Entwicklung. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn