Начало работы с Java и Zookeeper

Начало работы с Java и Zookeeper

1. обзор

Apache ZooKeeperis a distributed coordination service, который упрощает разработку распределенных приложений. Он используется такими проектами, как Apache Hadoop, HBase иothers, для различных сценариев использования, таких как выбор лидера, управление конфигурацией, координация узлов, управление арендой серверов и т. Д.

Nodes within ZooKeeper cluster store their data in a shared hierarchal namespace, который похож на стандартную файловую систему или древовидную структуру данных.

В этой статье мы рассмотрим, как использовать Java API Apache Zookeeper для хранения, обновления и удаления информации, хранящейся в ZooKeeper.

2. Setupс

Последнюю версию библиотеки Java Apache ZooKeeper можно найтиhere:


    org.apache.zookeeper
    zookeeper
    3.4.11

3. Модель данных ZooKeeper - ZNode

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

Каждый узел в дереве ZooKeeper называется ZNode.

Каждый ZNode поддерживает номера версий и временные метки для любых изменений данных или ACL. Кроме того, это позволяет ZooKeeper проверять кэш и координировать обновления.

4. Монтаж

4.1. Монтаж

Последнюю версию ZooKeeper можно загрузить сhere. Перед тем как это сделать, нам нужно убедиться, что мы отвечаем системным требованиям, описаннымhere.

4.2. Автономный режим

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

Примечание. В автономном режиме репликация отсутствует, поэтому в случае сбоя процесса ZooKeeper служба перестанет работать.

5. Примеры интерфейса командной строки ZooKeeper

Теперь мы будем использовать интерфейс командной строки (CLI) ZooKeeper для взаимодействия с ZooKeeper:

bin/zkCli.sh -server 127.0.0.1:2181

Выше команда запускает автономный экземпляр локально. Давайте теперь посмотрим, как создать ZNode и хранить информацию в ZooKeeper:

[zk: localhost:2181(CONNECTED) 0] create /MyFirstZNode ZNodeVal
Created /FirstZnode

Мы только что создали ZNode‘MyFirstZNode’ в корне иерархического пространства имен ZooKeeper и записали в него‘ZNodeVal’.

Поскольку мы не передали никаких флагов, созданный ZNode будет постоянным.

Теперь давайте запустим команду‘get' для получения данных, а также метаданных, связанных с ZNode:

[zk: localhost:2181(CONNECTED) 1] get /FirstZnode

“Myfirstzookeeper-app”
cZxid = 0x7f
ctime = Sun Feb 18 16:15:47 IST 2018
mZxid = 0x7f
mtime = Sun Feb 18 16:15:47 IST 2018
pZxid = 0x7f
cversion = 0
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 22
numChildren = 0

Мы можем обновить данные существующегоZNode с помощью операцииset.

Например:

set /MyFirstZNode ZNodeValUpdated

Это обновит данные вMyFirstZNode сZNodeVal доZNodeValUpdated.

6. Пример ZooKeeper Java API

Давайте теперь посмотрим на Zookeeper Java API и создадим узел, обновим узел и извлечем некоторые данные.

6.1. Пакеты Java

Привязки Java ZooKeeper состоят в основном из двух пакетов Java:

  1. org.apache.zookeeper:, который определяет основной класс клиентской библиотеки ZooKeeper вместе со многими статическими определениями типов и состояний событий ZooKeeper.

  2. org.apache.zookeeper.data: определяет характеристики, связанные с ZNodes, такие как списки контроля доступа (ACL), идентификаторы, статистика и т. д.

В реализации сервера также используются Java-интерфейсы ZooKeeper, такие какorg.apache.zookeeper.server,org.apache.zookeeper.server.quorum иorg.apache.zookeeper.server.upgrade.

Однако они выходят за рамки данной статьи.

6.2. Подключение к экземпляру ZooKeeper

Теперь давайте создадим классZKConnection, который будет использоваться для подключения и отключения от уже запущенного ZooKeeper:

public class ZKConnection {
    private ZooKeeper zoo;
    CountDownLatch connectionLatch = new CountDownLatch(1);

    // ...

    public ZooKeeper connect(String host)
      throws IOException,
      InterruptedException {
        zoo = new ZooKeeper(host, 2000, new Watcher() {
            public void process(WatchedEvent we) {
                if (we.getState() == KeeperState.SyncConnected) {
                    connectionLatch.countDown();
                }
            }
        });

        connectionLatch.await();
        return zoo;
    }

    public void close() throws InterruptedException {
        zoo.close();
    }
}

Чтобы использовать службу ZooKeeper, приложение должно сначала создать экземпляр объектаZooKeeper class, which is the main class of ZooKeeper client library.

В методеconnect мы создаем экземпляр классаZooKeeper. Кроме того, мы зарегистрировали метод обратного вызова для обработкиWatchedEvent от ZooKeeper для принятия соединения и, соответственно, завершения методаconnect, используя методcountdown дляCountDownLatch.

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

Клиентское приложение может вызывать API ZooKeeper, если его идентификатор сеанса остается действительным.

6.3. Клиентские операции

Теперь мы создадим интерфейсZKManager, который предоставляет различные операции, такие как создание ZNode и сохранение некоторых данных, выборка и обновление данных ZNode:

public interface ZKManager {
    public void create(String path, byte[] data)
      throws KeeperException, InterruptedException;
    public Object getZNodeData(String path, boolean watchFlag);
    public void update(String path, byte[] data)
      throws KeeperException, InterruptedException;
}

Давайте теперь посмотрим на реализацию вышеуказанного интерфейса:

public class ZKManagerImpl implements ZKManager {
    private static ZooKeeper zkeeper;
    private static ZKConnection zkConnection;

    public ZKManagerImpl() {
        initialize();
    }

    private void initialize() {
        zkConnection = new ZKConnection();
        zkeeper = zkConnection.connect("localhost");
    }

    public void closeConnection() {
        zkConnection.close();
    }

    public void create(String path, byte[] data)
      throws KeeperException,
      InterruptedException {

        zkeeper.create(
          path,
          data,
          ZooDefs.Ids.OPEN_ACL_UNSAFE,
          CreateMode.PERSISTENT);
    }

    public Object getZNodeData(String path, boolean watchFlag)
      throws KeeperException,
      InterruptedException {

        byte[] b = null;
        b = zkeeper.getData(path, null, null);
        return new String(b, "UTF-8");
    }

    public void update(String path, byte[] data) throws KeeperException,
      InterruptedException {
        int version = zkeeper.exists(path, true).getVersion();
        zkeeper.setData(path, data, version);
    }
}

В приведенном выше коде вызовыconnect иdisconnect делегируются ранее созданному классуZKConnection. Наш методcreate используется для создания ZNode по заданному пути из данных байтового массива. Только для демонстрационных целей мы оставили ACL полностью открытыми.

После создания ZNode является постоянным и не удаляется при отключении клиента.

Логика получения данных ZNode из ZooKeeper в нашем методеgetZNodeData довольно проста. Наконец, с помощью методаupdate мы проверяем наличие ZNode на заданном пути и получаем его, если он существует.

Кроме того, для обновления данных мы сначала проверяем существование ZNode и получаем текущую версию. Затем мы вызываем методsetData с путем к ZNode, данным и текущей версии в качестве параметров. ZooKeeper будет обновлять данные, только если переданная версия совпадает с последней версией.

7. Заключение

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

ZooKeeper также предоставляет элегантный API на основе Java для использования в коде клиентского приложения для беспрепятственного взаимодействия с ZooKeeper ZNodes.

И, как всегда, все исходники этого руководства можно найтиover on Github.