что такое sequence узел в zookeeper

Конфигурация кластера из трех узлов ZooKeeper и брокеров Apache Kafka

Доброго времени суток!

В этой статье рассмотрим настройку кластера из трех узлов ZooKeeper (служба координации распределенной системы), два из которых — брокеры сообщений Kafka, третий — управляющий.

В результате будет реализована следующая схема компонентов:

что такое sequence узел в zookeeper. image loader. что такое sequence узел в zookeeper фото. что такое sequence узел в zookeeper-image loader. картинка что такое sequence узел в zookeeper. картинка image loader.

Все компоненты на одной машине, для простоты воспользуемся встроенными консольными издателем (producer) и подписчиком (consumer) сообщений.

Модуль ZooKeeper встроен в пакет Kafka, используем его.

Установка и настройка

Установка пакета Kafka

В данном случае операционная система — Ubuntu 16.04 LTS.

Актуальные версии и подробная инструкция — на официальном сайте.

Создадим рабочие директории для трех узлов server_1, server_2 и server_3.

Конфигурация Kafka-брокера
(из директорий kafka_server_1, kafka_server_2 и kafka_server_3 соответственно)

Создание директорий для узлов ZooKeeper, запись id узлов в служебные файлы:

В случае возникновения проблем с правами доступа изменить их у директорий и файлов:

Запуск z-узлов и брокеров

Для первых двух узлов (kafka_server_1/, kafka_server_2/) запускаем скрипты ZooKeeper и Kafka-серверов, аргументы — соответствующие конфиг файлы:

Для третьего узла (kafka_server_3/) — только ZooKeeper.

Скрипты для остановки серверов:

Создание темы, консольного producer-а и consumer-а

Узнать список топиков на порту, информацию о каждом топике можно командой:

Leader — сервер с основным экземпляром партиции, replica — сервер, на котором информация дублируется, ISR — сервера, берущие на себя роль лидеров в случае отказа leader.

Console producer, console consumer создаем с помощью соответствующих скриптов:

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

Сервисы для zookeeper и kafka в systemctl

Для удобства запуска кластера можно создать сервисы в systemctl: zookeeper_1.service, zookeeper_2.service, zookeeper_3.service, kafka_1.service, kafka_2.service.

Редактируем файл /etc/systemd/system/zookeeper_1.service (директорию /home/user и пользователя user изменить на нужные).

Для сервисов zookeeper_2.service и zookeeper_3.service аналогично.

Активация и проверка работы сервисов

То же самое для zookeeper_2.service, zookeeper_3.service, kafka_1.service, kafka_1.service.

Источник

ZooKeeper или пишем сервис распределенных блокировок

disclaimer Так получилось, что последний месяц я разбираюсь с ZooKeeper, и у меня возникло желание систематизировать то, что я узнал, собственно пост об этом, а не о сервисе блокировок, как можно было подумать исходя из названия. Поехали!

При переходе от многопоточного программирования к программированию распределенных систем многие стандартные техники перестают работать. Одной из таких техник являются блокировки (synchronized), так как область их действия ограничена одним процессом, следовательно, они не только не работают на разных узлах распределенной системы, но так же не между разными экземплярами приложения на одной машине; получается, что нужен отдельный механизм для блокировок.

Поддерживаемые операции

existsпроверяет существование znode и возвращает его метаданные
createсоздает znode
deleteудаляет znode
getDataполучает данные ассоциированные с znode
setDataассоциирует новые данные с znode
getChildrenполучает детей указанного znode
syncдожидается синхронизации узла кластера, к которому мы подсоединены, и мастера.

Эти операции можно разделить по следующим группам

callbackCAS
existsdelete
getDatasetData
getChildrencreate
sync

Callback — read-only операции, к которым можно указать коллбеки, коллбек сработает, когда запрашиваемая сущность измениться. Коллбек сработает не более одного раза, в случае, когда нужно постоянно мониторить значение, в обработчике события нужно постоянно переподписываться.

CAS — write запросы. Проблема конкурентного доступа в ZooKeeper’е решена через compare-and-swap: с каждым znode храниться его версия, при изменении её нужно указывать, если znode уже был изменен, то версия не совпадает и клиент получит соответственное исключение. Операции из этой группы требуют указания версии изменяемого объекта.

create — создает новый znode (пару ключ/значение) и возвращает ключ. Кажется странным, что возвращается ключ, если он указывается как аргумент, но дело в том, что ZooKeeper’у в качестве ключа можно указать префикс и сказать, что znode последовательный, тогда к префиксу добавиться выровненное число и результат будет использоваться в качестве ключа. Гарантируется, что создавая последовательные znode с одним и тем же префиксом, ключи будут образовывать возрастающую (в лексико-графическом смысле) последовательность.

Помимо последовательных znode, можно создать эфемерные znode, которые будут удалены, как только клиент их создавший отсоединиться (напоминаю, что соединение между кластером и клиентом в ZooKeeper держится открытым долго). Эфемерные znode не могут иметь детей.

Znode может одновременно быть и эфемерным, и последовательным.

sync — синхронизует узел кластера, к которому подсоединен клиент, с мастером. По хорошему не должен вызываться, так как синхронизация происходит быстро и автоматически. О том, когда её вызывать, будет написано ниже.

На основе последовательных эфемерных znode и подписках на их удаление можно без проблем создать систему распределенных блокировок.

Система распределенных блокировок

На самом деле все придумано до нас — идем на сайт ZooKeeper в раздел рецептов и ищем там алгоритм блокировки:

Для проверки усвоения материала попробуйте понять самостоятельно, по убыванию или по возрастанию нужно сортировать список в шаге 4.

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

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

В теории можно было бы и закончить, но как показала практика, начинается самое интересное — wtf‘ки. Под wtf‘ами я имею ввиду расхождение моих интуитивных представлений о системе с её реальном поведением, внимание, wtf не несет оценочного суждения, кроме того я прекрасно понимаю, почему создатели ZooKeeper’а пошли на такие архитектурные решения.

WTF #1 — выворачиваем код на изнанку

Любой метод API может кинуть checked exception и обязать вас его обработать. Это не привычно, но правильно, так как первое правило распределенных систем — сеть не надежна. Одно из исключений, которое может полететь — пропажа соединения (моргание сети). Не стоит путать пропажу соединения с узлом кластера (CONNECTIONLOSS), при который клиент сам его восстановит с сохраненной сессией и коллбеками (подключится к другому или будет ждать), и принудительное закрытие соединения со стороны кластера и потерей всех коллбеков (SESSIONEXPIRED), в данном случае задача по восстановлению контекста ложится на плечи программиста. Но мы отошли от темы…

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

Вам это ничего не напоминает? C одной стороны — события, с другой — необходимость «играть» с потоком выполнения программы, по-моему где-то рядом continuation и монады.

В общем, я оформил шаги программы в виде:

Добавив нужные комбинаторы можно строить следующие программы, где-то используя идемпотентность шагов, где-то явно подчищая мусор:

что такое sequence узел в zookeeper. image loader. что такое sequence узел в zookeeper фото. что такое sequence узел в zookeeper-image loader. картинка что такое sequence узел в zookeeper. картинка image loader.

WTF #2 — сервер главный

Можно сказать, что в ZooKeeper сервер (кластер) является главным, а у клиентов практически нет прав. Иногда это доходит до абсолюта, например… В конфигурации ZooKeeper есть такой параметр как session timeout, он определяет на сколько максимум может пропадать связь между кластером и клиентом, если максимум превышен, то сессия этого клиента будет закрыта и все эфемерные znode этого клиента удаляться; если связь все-таки восстановиться — клиент получит событие SESSIONEXPIRED. Так вот, клиент при пропажи соединения (CONNECTIONLOSS) и превышении session timeout тупо ждет и нечего не делает, хотя, по идеи он мог догадаться о том, что сессия сдохла и сам своим обработчикам кинуть SESSIONEXPIRED.

Из-за такого поведения разработчик в какие-то моменты рвать на себе волосы, допустим вы подняли сервер ZooKeeper и пытаетесь к нему подключиться, но ошиблись в конфиге и стучитесь не по тому адресу, или не по тому порту, тогда, согласно описанному выше поведению, вы просто будете ждать, когда клиент перейдет в состояние CONNECTED и не получите никакого сообщения об ошибке, как это было бы в случае с MySQL или чем-нибудь подобным.

WTF #3 — переполняется int

Допустим вы реализовали блокировки согласно описанному выше алгоритме и запустили это дело в highload продакшен, где, допустим вы берете 10MM блокировок в день. Где-то через год вы обнаружите, что попали в ад — блокировки перестанут работать. Дело в том, что через год у znode _locknode_ счетчик cversion переполниться и нарушиться принцип монотонно возрастающей последовательности имен последовательных znode, а на этом принципе основана наша реализация блокировок.

Что делать? Нужно периодически удалять/создавать заново _locknode_ — при этом счетчик ассоциированный с ним сброситься и принцип монотонной последовательности снова нарушится, но дело в том, что znode можно удалить только когда у него нет детей, а теперь сами догадайтесь, почему сброс cversion у _locknode_, когда в нем нет детей не влияет на алгоритм блокировки.

WTF #4 — quorum write, но не read

Когда ZooKeeper вернул ОК на запрос записи это означает что данные записались на кворум (большинство машин в кластере, в случае 3х машин, кворум состоит из 2х), но при чтении пользователь получает данные с той машины, к которой он подключился. То есть возможна ситуация, когда пользователь получает старые данные.

В случае, когда клиенты не общаются иначе как только через ZooKeeper это не составляет проблемы, так как все операции в ZooKeeper строго упорядочены и тогда нет возможности узнать о том, что событие произошло кроме, как дождаться его. Догадайтесь сами, почему из того следует, что все хорошо. На самом деле, клиент может знать, что данные обновились, даже если никто ему не сказал — в случае, когда он сам произвел изменения, но ZooKeeper поддерживает read your writes consistency, так что и это не проблема.

Но все-же, если один клиент узнал об изменении части данных через канал связи все ZooKeeper, ему может помочь принудительная синхронизация — именно для этого нужна команда sync.

Производительность

Большинство распределенных key/value хранилищ используют распределенность для хранения большого объема данных. Как я уже писал, данные которые хранит в себе ZooKeeper не должны превышать размер оперативной памяти, спрашивается, зачем ему распределенность — она используется для обеспечения надежности. Вспоминая про необходимость набрать кворум на запись, не удивительно падение производительности на 15% при использовании кластера из трех машин, по сравнению с одной машиной.

Другая особенность ZooKeeper состоит в том, что он обеспечивает персистентность — за неё тоже нужно так как во время обработки запроса включено время записи на диск.

Тестировал я на локальном ноуте, да-да это сильно напоминает:

что такое sequence узел в zookeeper. 298d82bfad10e68896ad3346c34b1485. что такое sequence узел в zookeeper фото. что такое sequence узел в zookeeper-298d82bfad10e68896ad3346c34b1485. картинка что такое sequence узел в zookeeper. картинка 298d82bfad10e68896ad3346c34b1485.
DevOps Borat
Big Data Analytic is show 90% of devops which are use word ‘benchmark’ in sentence are also use word ‘laptop’ in same sentence.

но очевидно, что ZooKeeper лучше всего себя показывает в в конфигурации из одной ноды, с быстрым диском и на небольшом кол-ве данных, поэтому мой X220 c SSD и i7 идеально для этого подходил. Тестировал я преимущественно запросы на запись.

Потолок по производительности был где-то около 10K операций в секунду при интенсивной записи, на запись уходит от 1ms, следовательно, с точки зрения одного клиента, сервер может работать не быстрее 1K операций в секунду.

Что это значит? В условиях, когда мы не упираемся в диск (утилизация ssd на уровне 10%, для верности попробовал так же разместить данные в памяти через ramfs — получил небольшой прирост в производительности), мы упираемся в cpu. Итого, у меня получилось, что ZooKeeper всего в 2 раза медленнее, чем те числа, которые указали на сайте его создатели, что не плохо, если учесть, что они знают, как из него выжать все.

Резюме

Не смотря на все, что я здесь написал, ZooKeeper не так плох, как может показаться. Мне нравится его лаконичность (всего 7 команд), мне нравиться то, как он подталкивает и направляет своим API программиста к правильному подходу при разработке распределенных систем, а именно, в любой момент все может упасть, потому каждая операция должна оставлять систему в консистентном состоянии. Но это мои впечатления, они не так важны, как то, что ZooKeeeper хорошо решает задачи, для которых он был создан, среди которых: хранение конфигов кластера, мониторинг состояние кластера (кол-во подключенных нод, статус нод), синхронизация нод (блокировки, барьеры) и коммуникация узлов распределенной системы (a-la jabber).

О распределенных блокировках

Возвращаясь к алгоритму блокировки, описанному выше, могу сказать, что он не работает, точнее работает ровно до тех пор, пока действия внутри критической секции происходят над тем же и только тем же кластером ZooKeeper, что используется для блокировки. Почему так? — Попробуйте догадаться сами. А в следующей статье я напишу как сделать распределенные блокировки более честными и расширить класс операций внутри критической секции на любое key/value хранилище с поддержкой CAS.

Источник

Обзор возможностей библиотеки Apache Curator для Apache Zookeeper

что такое sequence узел в zookeeper. image loader. что такое sequence узел в zookeeper фото. что такое sequence узел в zookeeper-image loader. картинка что такое sequence узел в zookeeper. картинка image loader.

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

Zookeeper — продукт сложный. Несмотря на солидный возраст, периодически в нем обнаруживаются те или иные ошибки. Однако, это лишь следствие его возможностей, которые помогают сделать жизнь легче многим разработчикам распределенных систем. Далее, я рассмотрю некоторые особенности Zookeeper, которые помогут понять лучше его возможности, а затем перейдем к библиотеке Apache Curator (Netflix), которая делает жизнь разработчиков распределенного ПО приятной и предлагает множество готовых рецептов для реализации распределенных объектов координации.

Apache Zookeeper

Как уже ранее было отмечено, Zookeeper — жизненно важный компонент распределенных систем. Базу данных Zookeeper проще всего представить в виде дерева, похожего на файловую систему, при этом каждый элемент дерева идентифицируется путем (/a/path/to/node) и хранит в себе произвольные данные. Таким образом, с помощью Zookeper вполне можно организовать иерархическое распределенное хранилище данных, а также другие интересные конструкции. Полезность и широкая распространенность Zookeeper-а обеспечивается рядом важнейших свойств, которые перечислены далее.

Распределенный консенсус

Консенсус обеспечивается с помощью алгоритма ZAB, данный алгоритм обеспечивает свойства C(consistency) и P(partition tolerance) CAP-теоремы, что означает целостность и устойчивость к разделению, жертвуя доступностью. На практике это приводит к следующим эффектам:

Консенсус — способность распределенной системы каким-то образом прийти к соглашению о ее текущем состоянии. Zookeeper использует алгоритм ZAB, часто применяются и другие алгоритмы — Raft,
Raft.

Эфемерные узлы

Клиент, устанавливая соединение с кластером Zookeeper, создает сессию. В рамках сессии существует возможность создавать узлы, которые будут видны другим клиентам, но, время существования которых равно времени жизни сессии. При завершении сессии данные узлы будут удалены. Такие узлы имеют ограничения — они могут быть только терминальными и не могут иметь потомков, то есть, нельзя иметь эфемерные поддеревья. Эфемерные узлы часто применяются с целью
реализации систем обнаружения сервисов.

Представим, что у нас есть несколько экземпляров сервиса, между которыми производится балансировка нагрузки. Если какой-то из экземпляров появляется, то для него создается эфемерный узел, в котором находится адрес сервиса, а при аварии сервиса этот узел удаляется и более не может использоваться для балансировки. Эфемерные узлы применяются очень часто.

Подписка на события узла

Клиент может подписаться (watch) на события узлов и получать обновления при возникновении каких-либо событий, связанных с данными узлами. Однако, тут тоже есть ограничение — после возникновения события на узле, подписка снимается и ее необходимо восстанавливать заново, при этом, очевидно, существует возможность пропуска других событий, которые возникают на данном узле. В связи с данным фактом, возможность использования данной функции достаточно ограничена.

Например, в рамках сервисов обнаружения ее применять можно, для реакции на изменение конфигурации, но необходимо помнить, что после установки подписки необходимо выполнить операцию «вручную», чтобы убедиться, что пропуска изменения состояния не произошло.

Последовательные узлы

Zookeeper позволяет создавать узлы, имена которых формируются с добавлением последовательно возрастающих чисел, при этом данные узлы могут быть эфемерными. Эта возможность широко применяется как для решения прикладных задач (например, все однотипные сервисы, регистрируют себя как эфемерные узлы), так и для реализации «рецептов» Zookeeper, к примеру, справедливой распределенной блокировки.

Версии узлов

Версии узлов позволяют определить было ли изменение узла между чтением и записью, то есть при операции set можно указать ожидаемую версию узла, в том случае, если она не совпадет, значит, что изменение узла было произведено другим клиентом и требуется заново вычитать состояние. Данный механизм позволяет реализовать упорядоченное изменение состояния данных, например, при реализации «рецепта» распределенный счетчик.

ACL на узлы

Существует возможность задавать для узлов ограничения доступа, определяемые ACL, что предназначено для защиты данных от недоверенных приложений. Стоит отметить, что, конечно, ACL не защищают от перегрузок, которые может создать вредоносный клиент, предоставляя только механизм ограничения доступа к содержимому.

TTL на узлы

Zookeeper позволяет устанавливать узлам TTL, по истечении которого (если нет обновлений) узел будет удален. Данная функциональность появилась сравнительно недавно.

Серверы-наблюдатели

Существует возможность подключения к кластеру серверов в режиме наблюдатель (observer), которые могут использоваться для выполнения операций чтения, что очень полезно в тех случаях, когда нагрузка на кластер, генерируемая операциями записи является высокой. С использованием серверов-наблюдателей проблема может быть решена. Может возникнуть вопрос, почему бы просто в кластер не добавлять обычные узлы? Ответ кроется в алгоритме консенсуса — чем больше узлов, позволяющих писать данные, тем дольше будет тратиться времени на достижение консенсуса и тем меньше будет производительность кластера на запись. Серверы-наблюдатели не участвуют в консенсусе, а поэтому не влияют на производительность операций записи.

Синхронизация времени на узлах

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

Конечно, в бочке меда должен быть деготь и он действительно есть — Zookeeper имеет свойства, которые могут ограничивать его применение. Есть даже выражение, которое достаточно иронично описывает сложности работы с Zookeeper — Single Cluster of Failure © Pinterest, что саркастически демонстрирует тот факт, что, стремясь избавиться от единой точки отказа с помощью распределенной системы, используя Zookeeper, можно столкнуться с ситуацией, когда он станет той самой точкой отказа.

База данных Zookeeper должна помещаться в RAM

Zookeeper загружает базу в память и держит ее там. Если база данных не помещается в RAM, то она будет помещена в Swap, что приведет к существенной деградации производительности. Если БД большая, требуется сервер с достаточно большим объемом RAM (что, впрочем, не является проблемой в настоящее время, когда 1TB RAM на сервере — далеко не предел).

Время таймаута сессии

Если при настройке клиента выбрать неверно время таймаута сессии, то это может вести к непредсказуемым последствиям, которые будут обостряться при увеличении нагрузки на кластер и выходе из строя части узлов кластера. Пользователи стремятся уменьшить время сессии (по умолчанию 30 секунд), чтобы увеличить сходимость системы, поскольку эфемерные узлы будут удаляться быстрее, но это ведет к меньшей стабильности системы под нагрузкой.

Деградация производительности от количества узлов в кластере

Обычно, в кластере используют 3 узла, которые участвуют в достижении консенсуса, желание добавить дополнительные узлы существенно снизит производительность операций записи. Количество узлов должно быть нечетным (требование алгоритма ZAB), соответственно, расширение кластера до 5, 7, 9 узлов будет негативно влиять на производительность. Если проблема именно в операциях чтения — используйте узлы-наблюдатели.

Максимальный размер данных в узле

Максимальный размер данных в узле ограничен 1MB. В случае, если требуется хранить большие объемы данных, Zookeeper не подойдет.

Максимальное количество узлов в листинге потомков

Zookepeer не накладывает на то, сколько у узла может быть потомков, однако, максимальный размер пакета данных, который сервер может отправить клиенту составляет 4МБ (jute.maxbuffer). Если у узла такое количество потомков, что их перечень не помещается в один пакет, то, к сожалению, не существует способа получить сведения о них. Данное ограничение обходится с помощью организации иерархических «псевдоплоских» списков таким же образом, каким строятся кэши в файловой системе, имена или дайджесты объектов разбиваются на части и организуются в иерархическую структуру.

Несмотря на недостатки, достоинства их перевешивают, что делает Zookeeper важнейшим компонентом многих распределенных экосистем, например, Cloudera CDH5, или DC/OS, Apache Kafka и других.

Zookeeper для разработчика

Поскольку Zookeeper реализован с использованием языка Java, то в средах JVM его использование является органичным, к примеру, достаточно легко запустить сервер или даже кластер серверов из Java и использовать его для реализации интеграционных или smoke-тестов приложения без необходимости развертывания стороннего сервера. Однако, API клиента Zookeeper достаточно низкоуровневый, что, хотя и позволяет выполнять операции, но напоминает заплыв против течения реки. Кроме того, требуется глубокое понимание основ Zookeeper, чтобы правильно реализовать обработку исключительных ситуаций. К примеру, когда я использовал для работы с Zookeeper базовый интерфейс, отладка и поиск ошибок в коде распределенной координации и обнаружения доставляли достаточно большие проблемы и требовали существенное время.

Однако, решение существует и оно было подарено сообществу разработчиком Netflix Джорданом Циммерманом. Знакомьтесь, Apache Curator.

Apache Curator

На главной странице проекта расположена цитата:

что такое sequence узел в zookeeper. image loader. что такое sequence узел в zookeeper фото. что такое sequence узел в zookeeper-image loader. картинка что такое sequence узел в zookeeper. картинка image loader.

Это утверждение на 100% отражает суть Curator. Начав использовать данную библиотеку, я обнаружил, что код работы с Zookeeper стал простым и понятным, а количество ошибок и время на их устранение снизилось кратно. Если, как ранее было сказано — стандартный клиент напоминает заплыв против течения, то с куратором ситуация меняется на 180 градусов. Кроме того, в рамках Curator-а реализовано большое количество готовых рецептов, которые я обзорно рассмотрю далее.

Базовый API

API выполнен в форме исключительно удобного текучего интерфейса, что позволяет просто и лаконично определять требуемые действия. К примеру (далее, примеры приводятся на языке Scala):

что может быть переведено как «создай узел или, если существует, просто установи данные для пути «/object/path» и запиши в него byteArray».

«создай узел типа последовательный и эфемерный для пути «/head/child000000XXXX» и запиши в него byteArray». Еще несколько примеров могут быть найдены на этой странице руководства.

Асинхронные операции

При использовании Scala использование асинхронного интерфейса не кажется оправданным, поскольку функциональность может быть легко реализована с использованием Scala Future, что позволяет коду сохранить особенности scala-way разработки. Однако, в случае Java и других JVM языков, данный интерфейс может быть полезным.

Поддержка схем данных

Zookeeper не поддерживает семантику хранимых данных. Это означает, что разработчики самостоятельно несут ответственность за то, в каких форматах хранятся данные и по каким путям они расположены. Это может стать неудобным во многих случаях, например, когда в проект приходят новые разработчики. Для решения данных проблем Curator поддерживает схемы данных, которые позволяют задавать ограничения на пути и типы узлов, в рамках данных путей. Схема, создаваемая из конфигурации, может быть представлена в формате Json:

Поддержка миграций

Миграции Curator чем-то напоминают Liquibase, только для Zookeeper. С их помощью возможно отражать эволюцию базы данных в новых версиях продукта. Миграция состоит из набора последовательно выполняемых операций. Каждая операция представлена некоторыми преобразованиями над БД Zookeeper. Curator самостоятельно отслеживает примененность миграций с помощью Zookeeper. Данная функция может быть использована в процессе развертывания новой версии приложения. Подробно миграции описаны на соответствующей странице руководства.

Тестовый сервер и тестовый кластер

Для упрощения тестирования, Curator позволяет встроить сервер или даже кластер серверов Zookeeper в приложение. Данную задачу можно достаточно просто решить и без использования Curator, только с Zookeeper, но Curator предоставляет более лаконичный интерфейс. К примеру, в случае Zookeeper без Curator:

Рецепты Curator

Рецепты Curator — основной мотив использования данной библиотеки для реализации распределенных механизмов взаимодействия процессов. Далее, перечислим основные рецепты, которые поддерживаются Curator и как они могут применяться. Некоторые рецепты я не применял на практике, поэтому для них дан максимально приближенный к руководству перевод.

Выбор лидера

Данные рецепты предназначены для реализации отказоустойчивой модели выполнения процессов, в рамках которой существует текущий лидер и несколько процессов находится в горячем резерве. Как только лидер перестает выполнять свои функции, другой процесс становится лидером. Существует два подходящих рецепта:

Блокировки

Блокировки — один из важнейших механизмов распределенной межпроцессной синхронизации. Curator предоставляет широкий набор объектов блокировок:

Барьеры

Счетчики

Очереди

Хочу заметить, что Zookeeper — не лучший кандидат для организации интенсивных распределенных очередей, если требуется обеспечить пропуск большого количества сообщений, то рекомендую воспользоваться специально предназначенным решением, например, Apache Kafka, RabbitMQ или другими. Тем не менее, Curator предоставляет набор рецептов для поддержки очередей:

Заключение

Библиотека Apache Curator безусловно стоит того, чтобы рассмотреть ее к применению, она является выдающимся образцом инженерного труда и позволяет значительно упростить взаимодействие с Apache Zookeeper. К недостаткам библиотеки можно отнести малый объем документации, что повышает входной барьер для начинающих разработчиков. В своей практике мне не раз требовалось изучать исходные коды библиотеки, чтобы понять как именно работает тот или иной рецепт. Однако, это дает и положительный эффект — глубокое понимание реализации позволяет совершать меньше логических ошибок, основанных на предположениях.

Необходимо отметить, что разработчики Curator рекомендуют изучить документацию Zookeeper до того, как начать использовать библиотеку. Это очень разумный совет, поскольку Zookeeper является продуктом, для эффективного использования которого необходимо понимать как именно он функционирует, а не только знать его API. Эти затраты безусловно окупятся, а в руках опытного инженера возможности Zookeeper позволяет создавать надежные и производительные распределенные системы.

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *