Zookeeper - API

ZooKeeper có liên kết API chính thức cho Java và C. Cộng đồng ZooKeeper cung cấp API không chính thức cho hầu hết các ngôn ngữ (.NET, python, v.v.). Sử dụng API ZooKeeper, một ứng dụng có thể kết nối, tương tác, thao tác dữ liệu, điều phối và cuối cùng là ngắt kết nối khỏi nhóm ZooKeeper.

ZooKeeper API có một tập hợp các tính năng phong phú để có được tất cả các chức năng của nhóm ZooKeeper một cách đơn giản và an toàn. API ZooKeeper cung cấp cả phương thức đồng bộ và không đồng bộ.

Tập hợp ZooKeeper và API ZooKeeper hoàn toàn bổ sung cho nhau ở mọi khía cạnh và nó mang lại lợi ích cho các nhà phát triển một cách tuyệt vời. Hãy để chúng tôi thảo luận về liên kết Java trong chương này.

Kiến thức cơ bản về API ZooKeeper

Ứng dụng tương tác với nhóm ZooKeeper được gọi là ZooKeeper Client hoặc đơn giản Client.

Znode là thành phần cốt lõi của nhóm ZooKeeper và API ZooKeeper cung cấp một tập hợp nhỏ các phương thức để thao tác tất cả các chi tiết của znode với nhóm ZooKeeper.

Khách hàng nên làm theo các bước dưới đây để có tương tác rõ ràng và rõ ràng với nhóm ZooKeeper.

  • Kết nối với nhóm ZooKeeper. Tập hợp ZooKeeper chỉ định ID phiên cho máy khách.

  • Gửi nhịp tim đến máy chủ theo định kỳ. Nếu không, nhóm ZooKeeper hết hạn ID phiên và máy khách cần kết nối lại.

  • Lấy / đặt znodes miễn là ID phiên hoạt động.

  • Ngắt kết nối khỏi nhóm ZooKeeper, sau khi hoàn thành tất cả các nhiệm vụ. Nếu máy khách không hoạt động trong một thời gian dài, thì nhóm ZooKeeper sẽ tự động ngắt kết nối máy khách.

Java Binding

Hãy để chúng tôi hiểu bộ API ZooKeeper quan trọng nhất trong chương này. Phần trung tâm của API ZooKeeper làZooKeeper class. Nó cung cấp các tùy chọn để kết nối tập hợp ZooKeeper trong hàm tạo của nó và có các phương thức sau:

  • connect - kết nối với quần thể ZooKeeper

  • create - tạo một znode

  • exists - kiểm tra xem một znode có tồn tại hay không và thông tin của nó

  • getData - lấy dữ liệu từ một znode cụ thể

  • setData - đặt dữ liệu trong một znode cụ thể

  • getChildren - nhận tất cả các nút phụ có sẵn trong một znode cụ thể

  • delete - nhận một znode cụ thể và tất cả các con của nó

  • close - đóng kết nối

Kết nối với ZooKeeper Ensemble

Lớp ZooKeeper cung cấp chức năng kết nối thông qua phương thức khởi tạo của nó. Chữ ký của hàm tạo như sau:

ZooKeeper(String connectionString, int sessionTimeout, Watcher watcher)

Ở đâu,

  • connectionString - Máy chủ lưu trữ nhóm ZooKeeper.

  • sessionTimeout - thời gian chờ của phiên tính bằng mili giây.

  • watcher- một đối tượng thực hiện giao diện “Watcher”. Nhóm ZooKeeper trả về trạng thái kết nối thông qua đối tượng watcher.

Hãy để chúng tôi tạo một lớp trợ giúp mới ZooKeeperConnection và thêm một phương pháp connect. Cácconnect phương thức tạo một đối tượng ZooKeeper, kết nối với nhóm ZooKeeper, rồi trả về đối tượng.

Đây CountDownLatch được sử dụng để dừng (đợi) quá trình chính cho đến khi máy khách kết nối với nhóm ZooKeeper.

Nhóm ZooKeeper trả lời trạng thái kết nối thông qua Watcher callback. Lệnh gọi lại của Watcher sẽ được gọi khi máy khách kết nối với nhóm ZooKeeper và lệnh gọi lại của Watcher gọicountDown phương pháp của CountDownLatch để mở khóa, await trong quy trình chính.

Đây là mã hoàn chỉnh để kết nối với một nhóm ZooKeeper.

Mã hóa: 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();
   }
}

Lưu đoạn mã trên và nó sẽ được sử dụng trong phần tiếp theo để kết nối nhóm ZooKeeper.

Tạo một Znode

Lớp ZooKeeper cung cấp create methodđể tạo một znode mới trong nhóm ZooKeeper. Chữ ký củacreate phương pháp như sau:

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

Ở đâu,

  • path- Đường dẫn znode. Ví dụ: / myapp1, / ​​myapp2, / myapp1 / mydata1, myapp2 / mydata1 / myanothersubdata

  • data - dữ liệu để lưu trữ trong một đường dẫn znode cụ thể

  • acl- danh sách kiểm soát truy cập của nút được tạo. API ZooKeeper cung cấp giao diện tĩnhZooDefs.Idsđể có được một số danh sách acl cơ bản. Ví dụ, ZooDefs.Ids.OPEN_ACL_UNSAFE trả về danh sách acl cho các znodes đang mở.

  • createMode- loại nút, hoặc tạm thời, tuần tự hoặc cả hai. Đây làenum.

Hãy để chúng tôi tạo một ứng dụng Java mới để kiểm tra createchức năng của API ZooKeeper. Tạo một tệpZKCreate.java. Trong phương thức chính, hãy tạo một đối tượng kiểuZooKeeperConnection và gọi cho connect phương pháp kết nối với nhóm ZooKeeper.

Phương thức kết nối sẽ trả về đối tượng ZooKeeper zk. Bây giờ, hãy gọi chocreate phương pháp của zk đối tượng với tùy chỉnh pathdata.

Mã chương trình hoàn chỉnh để tạo một znode như sau:

Mã hóa: 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
      }
   }
}

Sau khi ứng dụng được biên dịch và thực thi, một znode với dữ liệu được chỉ định sẽ được tạo trong nhóm ZooKeeper. Bạn có thể kiểm tra nó bằng ZooKeeper CLIzkCli.sh.

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

Sự tồn tại - Kiểm tra sự tồn tại của một Znode

Lớp ZooKeeper cung cấp exists methodđể kiểm tra sự tồn tại của một znode. Nó trả về siêu dữ liệu của một znode, nếu znode được chỉ định tồn tại. Chữ ký củaexists phương pháp như sau:

exists(String path, boolean watcher)

Ở đâu,

  • path - Đường dẫn znode

  • watcher - giá trị boolean để chỉ định xem có xem một znode được chỉ định hay không

Hãy để chúng tôi tạo một ứng dụng Java mới để kiểm tra chức năng “tồn tại” của API ZooKeeper. Tạo một tệp “ZKExists.java” . Trong phương thức chính, tạo đối tượng ZooKeeper, “zk” bằng cách sử dụng đối tượng “ZooKeeperConnection” . Sau đó, gọi phương thức “tồn tại” của đối tượng “zk” với “đường dẫn” tùy chỉnh . Danh sách đầy đủ như sau -

Mã hóa: 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
      }
   }
}

Sau khi ứng dụng được biên dịch và thực thi, bạn sẽ nhận được kết quả bên dưới.

Node exists and the node version is 1.

Phương thức getData

Lớp ZooKeeper cung cấp getDatađể lấy dữ liệu được đính kèm trong một znode cụ thể và trạng thái của nó. Chữ ký củagetData phương pháp như sau:

getData(String path, Watcher watcher, Stat stat)

Ở đâu,

  • path - Đường dẫn znode.

  • watcher - Chức năng gọi lại kiểu Watcher. Nhóm ZooKeeper sẽ thông báo thông qua lệnh gọi lại của Watcher khi dữ liệu của znode được chỉ định thay đổi. Đây là thông báo một lần.

  • stat - Trả về siêu dữ liệu của một znode.

Hãy để chúng tôi tạo một ứng dụng Java mới để hiểu getDatachức năng của API ZooKeeper. Tạo một tệpZKGetData.java. Trong phương thức chính, tạo một đối tượng ZooKeeperzk sử dụng anh ấy ZooKeeperConnectionvật. Sau đó, hãy gọi chogetData phương thức của đối tượng zk với đường dẫn tùy chỉnh.

Đây là mã chương trình hoàn chỉnh để lấy dữ liệu từ một nút cụ thể -

Mã hóa: 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());
      }
   }
}

Khi ứng dụng được biên dịch và thực thi, bạn sẽ nhận được kết quả sau

My first zookeeper app

Và ứng dụng sẽ đợi thêm thông báo từ nhóm ZooKeeper. Thay đổi dữ liệu của znode được chỉ định bằng ZooKeeper CLIzkCli.sh.

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

Bây giờ, ứng dụng sẽ in đầu ra sau và thoát.

Hello

Phương pháp setData

Lớp ZooKeeper cung cấp setDatađể sửa đổi dữ liệu được đính kèm trong một znode cụ thể. Chữ ký củasetData phương pháp như sau:

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

Ở đâu,

  • path - Đường dẫn znode

  • data - dữ liệu để lưu trữ trong một đường dẫn znode xác định.

  • version- Phiên bản hiện tại của znode. ZooKeeper cập nhật số phiên bản của znode bất cứ khi nào dữ liệu bị thay đổi.

Bây giờ chúng ta hãy tạo một ứng dụng Java mới để hiểu setDatachức năng của API ZooKeeper. Tạo một tệpZKSetData.java. Trong phương thức chính, tạo một đối tượng ZooKeeperzk sử dụng ZooKeeperConnectionvật. Sau đó, hãy gọi chosetData phương pháp của zk đối tượng với đường dẫn được chỉ định, dữ liệu mới và phiên bản của nút.

Đây là mã chương trình hoàn chỉnh để sửa đổi dữ liệu được đính kèm trong một znode được chỉ định.

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

Sau khi ứng dụng được biên dịch và thực thi, dữ liệu của znode được chỉ định sẽ được thay đổi và nó có thể được kiểm tra bằng cách sử dụng ZooKeeper CLI, zkCli.sh.

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

Phương pháp getChildren

Lớp ZooKeeper cung cấp getChildrenđể lấy tất cả các nút con của một znode cụ thể. Chữ ký củagetChildren phương pháp như sau:

getChildren(String path, Watcher watcher)

Ở đâu,

  • path - Đường dẫn znode.

  • watcher- Chức năng gọi lại kiểu “Watcher”. Nhóm ZooKeeper sẽ thông báo khi znode được chỉ định bị xóa hoặc một phần tử con dưới znode được tạo / xóa. Đây là thông báo một lần.

Mã hóa: 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());
      }

   }

}

Trước khi chạy chương trình, chúng ta hãy tạo hai nút con cho /MyFirstZnode bằng cách sử dụng ZooKeeper CLI, zkCli.sh.

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

Bây giờ, biên dịch và chạy chương trình sẽ xuất ra các znodes đã tạo ở trên.

myfirstsubnode
mysecondsubnode

Xóa một Znode

Lớp ZooKeeper cung cấp deletephương pháp để xóa một znode được chỉ định. Chữ ký củadelete phương pháp như sau:

delete(String path, int version)

Ở đâu,

  • path - Đường dẫn znode.

  • version - Phiên bản hiện tại của znode.

Hãy để chúng tôi tạo một ứng dụng Java mới để hiểu deletechức năng của API ZooKeeper. Tạo một tệpZKDelete.java. Trong phương thức chính, tạo một đối tượng ZooKeeperzk sử dụng ZooKeeperConnectionvật. Sau đó, hãy gọi chodelete phương pháp của zk đối tượng với chỉ định path và phiên bản của nút.

Mã chương trình hoàn chỉnh để xóa một znode như sau:

Mã hóa: 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
      }
   }
}