ZooKeeper — это сервис для координации (синхронизации) распределенных процессов, предоставляющий простое и высокопроизводительное координационное ядро, на котором пользователи могут строить более сложные функции распределенной координации.
Несколько распределенных процессов управляют общим объектом данных памяти ZooKeeper ZNode через API, предоставляемый ZooKeeper, для достижения определенного согласованного поведения или результата.Этот режим по существу представляет собой модель параллелизма, основанную на совместном использовании состояния, которая согласуется с многопоточной моделью параллелизма Java. все их потоки или процессы являются «коммуникациями с общей памятью». Java не предоставляет напрямую какой-либо реагирующий интерфейс уведомлений для отслеживания изменения состояния объекта.Он может только тратить процессорное время без ответного опроса и повторных попыток или на основе какого-либо механизма активного уведомления (Notif), предоставляемого Java ( встроенная очередь) для реагирования на изменения состояния, но этот механизм требует зацикливания блокирующих вызовов. Когда ZooKeeper реализует совместное использование состояния этих распределенных процессов (данные ZNode, дочерние элементы), он принимает аналогичный асинхронный неблокирующий активный режим уведомления, а именно механизм наблюдения, основанный на соображениях производительности, который обеспечивает «общую связь состояния» между распределенные процессы.Более оперативные и эффективные, собственно, это и основная задача ZooKeeper — координация. Хотя Consul также реализует механизм Watch, это блокирующий длинный опрос.
- ZooKeeper VS JVM
С определенной точки зрения можно так сравнивать (личное мнение, можно обсуждать), ZooKeeper эквивалентен JVM, ZooKeeper содержит объекты состояния (ZNode) и лежащий в их основе механизм выполнения Zab распределенных процессов, а JVM содержит кучу (многопоточный общий доступ Большое количество областей хранения объектов) и спецификация ограничения корректности многопоточного выполнения JMM (модель памяти Java), JMM обеспечивает правильный порядок выполнения многопоточности. Протокол Zab делает внутренние операции изменения состояния ZooKeeper непосредственно последовательными по порядку, в то время как внутренняя JVM работает не по порядку и параллельно, и необходимо добавить дополнительные механизмы для обеспечения синхронизации (барьеры памяти, атомарные инструкции процессора) и когда состояние читается , JVM и ZooKeeper считывают старые данные при прямом чтении, но в ZooKeeper есть механизм Watch, который делает адаптивное чтение более эффективным, в то время как JVM может использовать базовый барьер памяти только для обновления общего состояния, чтобы другие потоки могли получать правильное чтение, когда они читать еще раз новые данные.
Интерфейс, предоставляемый ZooKeeper, делает выполнение всех распределенных процессов асинхронным и неблокирующим (алгоритм WaitFree), а внутренняя версия основана на работе CAS, в то время как JVM предоставляет множество блокирующих и неблокирующих интерфейсов, в том числе Synchronized, Летучие, AtomicOperations. При создании более сложных функций синхронизации или координации между потоками или распределенными процессами на основе интерфейса библиотека параллелизма Java напрямую предоставляет инструменты синхронизации, такие как блокировки, ограждения петель, семафоры и базовые абстрактные синхронизаторы очередей, в то время как ZooKeeper требует от пользователей создания различных распределенных функций координации. (распределенные блокировки, распределенная публикация и подписка, управление членством в кластере) на основе интерфейса. Как показано ниже:
ZooKeeper |
JVM |
|
Объект общего состояния |
ZNode | объекты в куче |
Базовый режим исполнения |
Заб последовательное выполнение | Многопроцессорное параллельное выполнение (барьеры памяти, атомарные машинные инструкции) |
API-интерфейс |
Получить, Watch_Get, Cas_Set, Существовать | Синхронизированный, изменчивый, окончательный, атомарный |
Функция координации или синхронизации |
Распределенная публикация-подписка, блокировки, блокировки чтения-записи | Инструмент параллельной синхронизации библиотек, компонент синхронизации на основе абстрактного синхронизатора очередей |
- Архитектура часов ZooKeeper
Общий процесс наблюдения показан на рисунке ниже.Клиент сначала успешно регистрирует статус узла, который он хочет отслеживать, на сервере ZooKeeper.В то же время клиент локально сохраняет информацию, относящуюся к прослушивателю, в WatchManager. Когда состояние данных, отслеживаемое сервером ZooKeeper, происходит. Когда происходит изменение, ZooKeeper будет активно уведомлять и отправлять соответствующую информацию о событии соответствующему клиенту сеанса, и клиент локально ответит на соответствующий обратный вызов.WatcherОбработчик.
- Смотреть функцию ZooKeeper
- Просмотр одноразовый, каждый раз нужно заново регистрироваться, и клиент при аварийном завершении сеанса не получает никакого уведомления, и не сводится к получению уведомления при быстром переподключении.
- Выполнение обратного вызова наблюдения в порядке, и клиент не увидит последние данные, прежде чем заметит уведомление об изменении данных внимания, и не обращайте внимания на то, чтобы не блокировать обратный вызов наблюдения всего клиента в логике обратного вызова наблюдения.
- Watch легковесен, WatchEvent — это наименьшая единица связи, и его структура содержит только статус уведомления, тип события и путь к узлу. Сервер ZooKeeper информирует клиента только о том, что произошло, а не о конкретном содержимом.
- Дизайн интерфейса наблюдателя
Как показано на рисунке выше, Watch разработан как интерфейс. Любой класс, реализующий интерфейс Watcher, является новым Watcher. Watcher содержит два класса перечисления, один KeeperState, который представляет состояние ZooKeeper, когда происходит событие, а другой событие. Типы событий в основном делятся на две категории (одна — изменение содержимого ZNode, другая — изменение дочерних узлов ZNode). Конкретное описание показано в следующей таблице.
KeeperState |
EventType |
TriggerCondition |
EnableCalls |
Desc |
SyncConnected (3)
|
None
(-1) |
Клиент и сервер успешно устанавливают сеанс | На этом этапе клиент подключен к серверу. | |
То же | NodeCreated
(1) |
Создается соответствующий узел данных, отслеживаемый Watcher. | Exists | То же |
То же | NodeDeleted
(2) |
Соответствующий узел данных, отслеживаемый Наблюдателем, удаляется. | Exists, GetData, and GetChildren | То же |
То же | NodeDataChanged
(3) |
Содержание данных и номер версии данных узлов данных, отслеживаемых Наблюдателем, изменяются. | Exists and GetData | То же |
То же | NodeChildrenChanged
(4) |
Список дочерних узлов узла данных, отслеживаемого Watcher, изменяется, и изменение содержимого дочерних узлов не срабатывает. | GetChildren | То же |
Disconnected
(0) |
None
(-1) |
Клиент отключается от сервера ZooKeeper | В этот момент клиент отключается от сервера. | |
Expried
(-112) |
None
(-1) |
Тайм-аут сеанса | В это время сеанс клиента недействителен и обычно одновременно получает исключение SessionExpiredException. | |
AuthFailed
(4) |
None
(-1) |
Обычно бывает два случая:
1. Используйте неправильную схему проверки разрешений 2. Ошибка проверки разрешений SASL |
Получено исключение AuthFailedException |
- Дизайн WatchEvent
Как показано на рисунке выше, WatchEvent имеет два режима представления, один из которых является логическим представлением, а именно WatchedEvent, который непосредственно инкапсулирует различные абстрактные логические состояния (KeeperState, EventType), которые подходят для внутренней обработки клиента и сервера, и другой. Это физическое представление, которое инкапсулирует большую часть базовой базовой структуры данных передачи (int, String) и реализует интерфейс сериализации, который в основном используется для базовой передачи данных.