Подключение к ZooKeeper через API

Содержание

ZooKeeper предоставляет API с байндингами для Java и C. API для других языков создаются и поддерживаются сообществом ZooKeeper.

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

Клиент ZooKeeper

Приложение, которое взаимодействует с сервером ZooKeeper, называется клиентом ZooKeeper.

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

  1. Создание соединения с сервером. При подключении сервер назначит ID сессии для клиента.

  2. Отправка heartbeat на сервер. Если клиент не будет активен какое-то время, то срок действия ID сессии закончится и клиенту придется подключаться повторно.

  3. Выполнение необходимых операций на сервере, например, получение или установка znodes.

  4. Отключение от сервера. Если клиент неактивен в течение длительного времени, сервер автоматически отключит его.

Узнать больше о разработке для Zookeeper можно в статье ZooKeeper Programmer’s Guide.

Java

Чтобы подключиться к серверу ZooKeeper с помощью Java API, необходимо настроить среду разработки и установить зависимости. Приведенный ниже пример кода создает соединение с сервером ZooKeeper, выводит подтверждение при успешном подключении и возвращает сообщение об ошибке, если подключиться не удалось.

Для выполнения примера используются следующие инструменты разработки: текстовый редактор Vi, виртуальная машина с CentOS 7 и компилятор Maven. При использовании других инструментов будет необходимо изменить некоторые шаги.

  1. Установите Maven.

  2. Напишите класс для создания соединения:

    package my.example.zookeeper;
    
    import java.io.IOException;
    import java.util.concurrent.CountDownLatch;
    
    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 Main {
       private class MyWatcher implements Watcher {
          public void process(WatchedEvent we) {
             if (we.getState() == KeeperState.SyncConnected) {
                connectedSignal.countDown();
             }
          }
       }
    
       private ZooKeeper zoo;
       final CountDownLatch connectedSignal = new CountDownLatch(1);
    
       public ZooKeeper connect(String host) throws IOException,InterruptedException {
    
          zoo = new ZooKeeper(host,2181,new MyWatcher());
    
          connectedSignal.await();
          return zoo;
       }
    
       public void close() throws InterruptedException {
          zoo.close();
       }
    
       public static void main(String[] args){
          try {
             Main app = new Main();
             app.connect("127.0.0.1");
             app.close();
          } catch (Exception e) {
    
          }
       }
    }
  3. Создайте файл pom.xml для сборки проекта с помощью Maven.

    Пример файла pom.xml
    <project>
            <modelVersion>4.0.0</modelVersion>
            <groupId>my.example.zookeeper</groupId>
            <artifactId>zoo-connect</artifactId>
            <version>0.1.0-SNAPSHOT</version>
            <packaging>jar</packaging>
      <properties>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
      </properties>
      <dependencies>
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-hdfs</artifactId>
                <version>2.7.1</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.zookeeper</groupId>
                <artifactId>zookeeper</artifactId>
                <version>3.4.11</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-common</artifactId>
                <version>2.7.1</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-core</artifactId>
                <version>1.2.1</version>
            </dependency>
    
            <dependency>
                <groupId>org.apache.hadoop</groupId>
                <artifactId>hadoop-client</artifactId>
                <version>2.7.1</version>
            </dependency>
      </dependencies>
    <build>
        <plugins>
          <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-assembly-plugin</artifactId>
                <version>3.1.0</version>
                <configuration>
                  <archive>
                    <manifest>
                      <addClasspath>true</addClasspath>
                      <mainClass>my.example.zookeeper.Main</mainClass>
                    </manifest>
                  </archive>
                    <descriptorRefs>
                        <descriptorRef>jar-with-dependencies</descriptorRef>
                    </descriptorRefs>
                </configuration>
                <executions>
                    <execution>
                        <id>assemble-all</id>
                        <phase>package</phase>
                        <goals>
                            <goal>single</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
          <plugin>
            <!-- Build an executable JAR -->
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-jar-plugin</artifactId>
            <version>3.1.0</version>
            <configuration>
              <archive>
                <manifest>
                  <addClasspath>true</addClasspath>
                  <mainClass>my.example.zookeeper.Main</mainClass>
                </manifest>
                 <addClasspath>true</addClasspath>
                  <mainClass>my.example.zookeeper.Main</mainClass>
                </manifest>
              </archive>
            </configuration>
          </plugin>
        </plugins>
      </build>
    
    </project>
  4. Соберите проект:

    $ mvn package
  5. Запустите Java-класс:

    $ java -jar <java-class>.jar

    Здесь <java-class> — имя Java-программы для подключения к HDFS.

В консоль будет выведена информация об успешном подключении:

23/12/14 19:43:34 INFO zookeeper.ZooKeeper: Initiating client connection, connectString=127.0.0.1 sessionTimeout=2181 watcher=my.example.zookeeper.Main$MyWatcher@433c675d
23/12/14 19:43:34 INFO zookeeper.ClientCnxn: Opening socket connection to server 127.0.0.1/127.0.0.1:2181. Will not attempt to authenticate using SASL (unknown error)
23/12/14 19:43:34 INFO zookeeper.ClientCnxn: Socket connection established to 127.0.0.1/127.0.0.1:2181, initiating session
23/12/14 19:43:34 INFO zookeeper.ClientCnxn: Session establishment complete on server 127.0.0.1/127.0.0.1:2181, sessionid = 0x1000000cebe0004, negotiated timeout = 4000
23/12/14 19:43:34 INFO zookeeper.ZooKeeper: Session: 0x1000000cebe0004 closed

C

Чтобы подключиться к серверу ZooKeeper с помощью C API, необходимо настроить среду разработки и установить зависимости. Приведенный ниже пример кода создает соединение с сервером ZooKeeper, выводит подтверждение при успешном подключении и возвращает сообщение об ошибке, если подключиться не удалось.

В примере используются следующие инструменты разработки: текстовый редактор Vi, виртуальная машина с Ubuntu 23.10 и компилятор GCC. При использовании других инструментов будет необходимо изменить некоторые шаги.

Другой пример клиента на C можно найти в репозитории Apache ZooKeeper.

Прежде чем создавать клиент ZooKeeper на C, необходимо загрузить библиотеку zookeeper.h или собрать ее самостоятельно используя инструмент для сборки ant. Если вы создаете многопоточный клиент, скомпилируйте его с флагом компилятора -DTHREADED, чтобы включить многопоточную версию библиотеки, а затем прилинкуйте ее к библиотеке zookeeper_mt. Если вы создаете однопоточный клиент, прилинкуйте библиотеку zookeeper_st и не используйте дополнительный флаг при компиляции.

Чтобы создать пример клиента ZooKeeper на языке C:

  1. Напишите программу для подключения к серверу. Например:

    #include <stdio.h>
    #include <stdlib.h>
    #include <zookeeper/zookeeper.h>
    #include <errno.h>
    
    static int completed = 0;
    
    void watcher(zhandle_t *zkH, int type, int state, const char *path, void *watcherCtx) {
        if (type == ZOO_SESSION_EVENT) {
            if (state == ZOO_CONNECTED_STATE) {
            } else if (state == ZOO_NOTCONNECTED_STATE ) {
            } else if (state == ZOO_EXPIRED_SESSION_STATE) {
                completed = 1;
                zookeeper_close(zkH);
            }
        }
    }
    
    void aget_strings_completion(int rc, const struct String_vector *strings, const void *data) {
        int i;
        if (strings) {
            for (i=0; i < strings->count; i++) {
                printf("\t%s\n", strings->data[i]);
            }
        }
        completed = 1;
    }
    
    int main(int argc, char *argv[]) {
        zoo_set_debug_level(ZOO_LOG_LEVEL_DEBUG);
        zhandle_t *handler = zookeeper_init("127.0.0.1:2181", watcher, 30000, NULL, NULL, 0);
        if (!handler) {
            return EXIT_FAILURE;
        }
        int rc = zoo_aget_children(handler, "/", 1, aget_strings_completion, NULL);
        if (rc) {
            fprintf(stderr, "Error %d\n", rc);
            return EXIT_FAILURE;
        }
        while (!completed) {
        }
        zookeeper_close(handler);
        return EXIT_SUCCESS;
    }
  2. Скомпилируйте код. Пример команды для компиляции:

    $ gcc main.c -o <program-name> -lzookeeper_mt

    Здесь <program-name> — название программы.

При настроенном выводе о работе клиента в консоль можно увидеть следующее:

2023-12-18 12:23:11,953:6904(0x7fa0e9d146c0):ZOO_INFO@check_events@2992: initiated connection to server 127.0.0.1:2181
2023-12-18 12:23:11,965:6904(0x7fa0e9d146c0):ZOO_INFO@finalize_session_establishment@2866: session establishment complete on server 127.0.0.1:2181, sessionId=0x1000000cebe0005, negotiated timeout=30000
2023-12-18 12:23:11,965:6904(0x7fa0e9d146c0):ZOO_DEBUG@finalize_session_establishment@2876: Calling a watcher for a ZOO_SESSION_EVENT and the state=ZOO_CONNECTED_STATE
2023-12-18 12:23:11,965:6904(0x7fa0e95136c0):ZOO_DEBUG@process_completions@3341: Calling a watcher for node [], type = -1 event=ZOO_SESSION_EVENT
2023-12-18 12:23:11,966:6904(0x7fa0e9d146c0):ZOO_DEBUG@zookeeper_process@3503: Queueing asynchronous response
2023-12-18 12:23:11,966:6904(0x7fa0e95136c0):ZOO_DEBUG@deserialize_response@3233: Calling COMPLETION_STRINGLIST for xid=0x658039b0 failed=0 rc=0
        zookeeper
        arenadata
        hadoop-ha
2023-12-18 12:23:11,966:6904(0x7fa0e95136c0):ZOO_DEBUG@do_completion@483: completion thread terminated
2023-12-18 12:23:11,966:6904(0x7fa0e9d146c0):ZOO_DEBUG@do_io@460: IO thread terminated
2023-12-18 12:23:11,966:6904(0x1a373c0):ZOO_INFO@zookeeper_close@3854: Closing zookeeper sessionId=0x1000000cebe0005 to 127.0.0.1:2181
Нашли ошибку? Выделите текст и нажмите Ctrl+Enter чтобы сообщить о ней