Подключение к ZooKeeper через API
ZooKeeper предоставляет API с байндингами для Java и C. API для других языков создаются и поддерживаются сообществом ZooKeeper.
API ZooKeeper позволяет приложениям подключаться к серверу, выполнять команды, манипулировать данными и координировать задачи.
Клиент ZooKeeper
Приложение, которое взаимодействует с сервером ZooKeeper, называется клиентом ZooKeeper.
Предпочтительный алгоритм взаимодействия клиента с сервером ZooKeeper выглядит следующим образом:
-
Создание соединения с сервером. При подключении сервер назначит ID сессии для клиента.
-
Отправка heartbeat на сервер. Если клиент не будет активен какое-то время, то срок действия ID сессии закончится и клиенту придется подключаться повторно.
-
Выполнение необходимых операций на сервере, например, получение или установка znodes.
-
Отключение от сервера. Если клиент неактивен в течение длительного времени, сервер автоматически отключит его.
Узнать больше о разработке для Zookeeper можно в статье ZooKeeper Programmer’s Guide.
Java
Чтобы подключиться к серверу ZooKeeper с помощью Java API, необходимо настроить среду разработки и установить зависимости. Приведенный ниже пример кода создает соединение с сервером ZooKeeper, выводит подтверждение при успешном подключении и возвращает сообщение об ошибке, если подключиться не удалось.
Для выполнения примера используются следующие инструменты разработки: текстовый редактор Vi, виртуальная машина с CentOS 7 и компилятор Maven. При использовании других инструментов будет необходимо изменить некоторые шаги.
-
Установите Maven.
-
Напишите класс для создания соединения:
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) { } } }
-
Создайте файл 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>
-
Соберите проект:
$ mvn package
-
Запустите 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:
-
Напишите программу для подключения к серверу. Например:
#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; }
-
Скомпилируйте код. Пример команды для компиляции:
$ 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