предисловие
Недавно присоединился к группе технических интересов отдела и получил задание на исследования для Zookeeper. В процессе исследования было обнаружено, что Zookeeper широко используется в отрасли благодаря своим функциям с открытым исходным кодом и превосходным характеристикам производительности, а также существует множество сценариев применения.На самом деле, основные принципы этих различных сценариев приложений схожи, так как пока вы действительно понимаете некоторые основные концепции и механизмы Zookeeper, вы можете использовать аналогию.
Итак, после того, как я впервые поделился принципом работы Zookeeper как центра регистрации сервисов и демо на стороне клиента с членами команды проекта, у меня возникла идея оформить тему, взяв это за отправную точку , и потихоньку подбираю свой блог Share the way.
Содержание этой статьи в основном знакомит со следующими моментами:
- What is Zookeeper
- Модель данных Zookeeper
- Sessions
- Watcher
1. Что такое зоопарк
Я впервые столкнулся с Zookeeper, потому что архитектура управления микросервисами, используемая в нашем проекте, — это Dubbo, а реестр служб, рекомендованный Dubbo, — это Zookeeper. По сути, Zookeeper — это распределенная служба координации, а координация и управление службами в распределенной среде — сложный процесс. ZooKeeper решает эту проблему благодаря простой архитектуре и API. ZooKeeper позволяет разработчикам сосредоточиться на основной логике приложения, не беспокоясь о распределенном характере приложения. Самое раннее приложение Zookeeper находится в экосистеме Hadoop, Apache HBase использует ZooKeeper для отслеживания состояния распределенных данных.
На самом деле, это хорошо понятно из названия, Zoo - зоопарк, Keeper - администратор, в зоопарке много видов животных, животных здесь можно сравнить с множеством сервисов в распределенной среде, а то, что делает Zookeeper, это управлять этими услугами.
Цель разработки ZooKeeper — инкапсулировать эти сложные и подверженные ошибкам службы распределенной согласованности, сформировать эффективный и надежный набор примитивов и предоставить пользователям ряд простых и удобных в использовании интерфейсов.
Примитивы: терминология операционной системы или компьютерных сетей. Это процесс, который состоит из нескольких инструкций и используется для выполнения определенной функции. Неделимый · Выполнение примитива должно быть непрерывным, прерывание во время выполнения не допускается.
Zookeeper предоставляет услуги в основном через: структуру данных + набор примитивов + механизм наблюдения.
Распределенные приложения в сочетании с Zookeeper могут достигать таких целей, как:Публикация/подписка на данные, балансировка нагрузки, службы именования, распределенная координация/уведомление, управление кластером, главные выборы, распределенные блокировки и распределенные очередии другие функции.
2. Модель данных Zookeeper
ZNode
Как видно из рисунка выше, модель данных Zookeeper очень похожа на дерево каталогов файловой системы Unix с иерархическим пространством имен. Каждый узел внутри называется — ZNode, узел может иметь дочерние узлы, а также позволяет хранить под этим узлом небольшое количество узлов данных. (Его можно понимать как файловую систему, которая позволяет файл или каталог)
(1) Метод ссылки на узел
ZNodes ссылаются на путь, как пути к файлам в Unix. Пути должны быть абсолютными, поэтому они должны иметь символы косой черты./
Начнем с того, что в дополнение к этому путь должен быть уникальным и не может быть изменен.
Эта функция также отражена в регистрации службы Dubbo.В исходном коде Dubbo есть глобальный класс.URL
, dubbo все время передает и сохраняет информацию о конфигурации в режиме шины, то есть информация о конфигурации помещается вURL
Информация о конфигурации может быть получена в любое время. Имя узла, которое Даббо записал при регистрации в реестре, было созданоURL
серединаURI
Он состоит из закодированной информации о конфигурации. Как показано ниже.
(2) Структура ZNode
Как упоминалось ранее, ZNode обладает характеристиками как файлов, так и каталогов.Он не только поддерживает структуры данных, такие как данные, метаинформация, ACL и метки времени, как файлы, но также может использоваться как часть идентификации пути, как каталоги.
ZNode состоит из следующих частей:
- Структура статистических данных
- Список управления операциями (ACL) — каждый узел имеет ACL для управления работой узла.Этот список определяет разрешения пользователя и ограничивает работу конкретного пользователя на целевом узле.
- CREATE - Разрешение на создание дочерних узлов
- READ — разрешение на получение данных узла и списка дочерних узлов.
- WRITE - Разрешение на обновление данных узла
- DELETE - разрешение на удаление дочерних узлов
- ADMIN - Разрешение на установку ACL узла
- Версии - ZNode имеет три версии данных
- version- текущая версия ZNode
- cversion- Версия текущего дочернего узла ZNode
- aversion- версия текущего списка ACL
- Zxid
- Это можно понять как Zookeeperпредставление метки времени, также можно понимать какномер транзакцииКонцепция чего-либо
- Если значение Zxid1 меньше значения Zxid2, то событие, соответствующее Zxid1, происходит до события, соответствующего Zxid2.
- У каждого сопровождающего узла ZooKeeper есть три значения Zxid, а именно:cZxid, mZxid, pZxid.
- cZxid: Время создания узла
- mZxid: время последней модификации узла
- pZxid: время последнего изменения списка дочерних узлов этого узла, содержимое дочернего узла не изменится pZxid
- Список управления операциями (ACL) — каждый узел имеет ACL для управления работой узла.Этот список определяет разрешения пользователя и ограничивает работу конкретного пользователя на целевом узле.
- поле данных
- дочерний узел
Вот несколько ключевых моментов, на которые стоит обратить внимание:
A. Информация о состоянии/Свойства узла
На следующем рисунке представлена информация о состоянии узла интерфейса микросервиса Dubbo, полученная с помощью zkClient на сервере с помощью команды get, например:
[zk: localhost:2181(CONNECTED) 0] get /dubbo/com.***.microservice.ucs.api.UniqueControlApi
127.0.0.1 // 节点数据Data域
cZxid = 0xdd59 //Created ZXID,表示该ZNode被创建时的事务ID
ctime = Thu Apr 18 15:17:11 CST 2019 //Created Time,表示该ZNode被创建的时间
mZxid = 0xdd59 //Modified ZXID,表示该ZNode最后一次被更新时的事务ID
mtime = Thu Apr 18 15:17:11 CST 2019 //Modified Time,表示该节点最后一次被更新的时间
pZxid = 0xdd62 //表示该节点的子节点列表最后一次被修改时的事务ID。注意,只有子节点列表变更了才会变更pZxid,子节点内容变更不会影响pZxid。
cversion = 4 //子节点的版本号
dataVersion = 0 //数据节点版本号
aclVersion = 0 //ACL版本号
ephemeralOwner = 0x0 //创建该节点的会话的sessionID。如果该节点是持久节点,那么这个属性值为0。
dataLength = 9 // Data域内容长度
numChildren = 4 // 子节点个数 众所周知,Dubbo接口子节点分为providers/configurators/routers/consumers
Б. Поле данных
Что касается домена данных, данные, хранящиеся на каждом узле в Zookeeper, должны бытьатомарная операция, то есть операция чтения получит все данные, относящиеся к узлу, а операция записи также заменит все данные узла.
Стоит отметить, что хотя Zookeeper может хранить данные,С точки зрения дизайна, он не предназначен для базы данных или хранения больших данных, напротив, он используется для управления данными планирования, такими как информация о файле конфигурации, информация о состоянии, местонахождение коллекции и т. д. в распределенных приложениях., эти данные обычно очень малы, КБ — это единица размера. ZNode также имеет ограничение на размер данных, не более 1M. Фактически, отсюда можно сделать вывод о применимости Zookeeper для распределенных центров конфигурации.
C. Zxid
В ZooKeeper,Операции, которые изменяют состояние сервера ZooKeeper, называются транзакционными операциями. Обычно он включает в себя такие операции, как создание и удаление узла данных, обновление содержимого данных, а также создание и аннулирование сеанса клиента.. Для каждого запроса на транзакцию ZooKeeper назначит ему глобально уникальныйномер транзакции, представленный Zxid.
Как видно из примера на рисунке выше, Zxid — это 64-битное число.топ 32называют эпохой, привыклиИдентифицирует в кластере ZookeeperLeader
узел, когдаLeader
Когда узел будет заменен, будет новая эпоха.последние 32 битаявляется возрастающей последовательностью. По этим Zxid мы можем косвенно определить глобальный порядок, в котором ZooKeeper обрабатывает эти запросы операций транзакций.
(3) Тип узла
Существует строго четыре типа узлов ZNode:Постоянный узел, Эфемерный узел, Постоянный последовательный узел, Эфемерный последовательный узел
- ПОСТОЯННЫЙ постоянный узел- Жизненный цикл узла не зависит от сеанса.После отключения клиента узел все еще существует.Узел может быть удален только клиентом, выполняющим операцию удаления;
- ЭФЕМЕРНЫЙ эфемерный узел- Период объявления ноды зависит от сессии, если клиент отключится, временная нода будет автоматически удалена. Кроме того,Временные узлы не могут иметь потомков.
-
ПОСЛЕДОВАТЕЛЬНЫЙ узел последовательности- При выборе создания последовательного узла ZooKeeper устанавливает путь znode, добавляя 10-значный порядковый номер к исходному имени. Например, если будет иметь путь
/myapp
znodes создаются как последовательные узлы, ZooKeeper изменит путь к/myapp0000000001
, и установите следующий порядковый номер на0000000002
. Если одновременно создаются два последовательных узла, ZooKeeper не будет использовать один и тот же номер для каждого znode.Последовательные узлы играют важную роль в блокировке и синхронизации.
3. Базовая работа сервиса Zookeeper
Как показано на рисунке выше отмечены девять основных операций сервиса Zookeeper, введитеZkClient.sh
,использоватьhelp
, вы можете увидеть эти операции.
[zk: localhost:2181(CONNECTED) 1] help
ZooKeeper -server host:port cmd args
stat path [watch] // 获取指定节点的状态信息
set path data [version] // setData操作
ls path [watch] // 查看某个节点下的所有子节点信息
delquota [-n|-b] path // 删除节点配额
ls2 path [watch] // ls + stat 两个命令结合
setAcl path acl // 设置ACL
setquota -n|-b val path // 设置节点配额,-n 是限制子节点个数 -b是限制节点数据长度
history // 历史命令
redo cmdno // 执行历史命令
printwatches on|off
delete path [version] // 删除指定路径节点,有子节点需要先删除子节点
sync path // 同步视图
listquota path // 查看节点配额信息
rmr path // 删除节点及其子节点
get path [watch] // 获取当前节点数据内容
create [-s] [-e] path data acl // 创建节点
addauth scheme auth
quit
getAcl path // 获取ACL
close
connect host:port
Как видно из команды, операция обновления ZooKeeper выполняетсяЕсть ограничения. delete или setData должны указать номер версии Znode для обновления, который мы можем найти, позвонив в exists.Если номера версий не совпадают, обновление завершится ошибкой..
Операция обновления ZooKeeperнеблокирующий. Поэтому, если клиент теряет обновление (из-за того, что другой процесс одновременно обновляет Znode), он может повторить попытку или сделать что-то еще, не блокируя выполнение другого процесса.
4. Сессии
В ZooKeeper клиентское соединение — этоTCP длинное соединение. Когда клиент запускается, он сначала устанавливает TCP-соединение с сервером.С первого установления соединения начинается жизненный цикл клиентской сессии.Через это соединение клиент может поддерживать действующий сеанс с сервером посредством обнаружения пульса, также может отправлять запросы на сервер Zookeeper и получать ответы, а также может получать уведомления о событиях Watch с сервера через это соединение.
Клиент отправляет тактовые импульсы через определенные промежутки времени, чтобы поддерживать сеанс в рабочем состоянии. Если ансамбли серверов ZooKeeper не получают пульс от клиента в течение периода, превышающего период, указанный при запуске сервера (время ожидания сеанса), он определяет, что клиент не работает.
Время ожидания сеанса обычно составляет миллисекунды. Когда сеанс завершается по какой-либо причине, эфемерные узлы, созданные во время этого сеанса, также удаляются.
5. Часы
я считаю,Часы - слушать события, является очень важной функцией Zookeeper и одной из основных функций, реализующих большинство функций Zookeeper. Проще говоря,Zookeeper позволяет клиенту регистрировать часы на указанном узле, когда происходят определенные события, сервер Zookeeper отправляет событиеасинхронныйУведомлять клиентов, которые заинтересованы (то есть зарегистрированы в Watches). Это можно понимать как систему подписки/публикации, не так ли?
Изменение Znode — это модификация данных, связанных с znode, или изменение дочерних элементов znode. Триггер смотрит только один раз. Если клиент хочет получить уведомление снова, он должен сделать это с помощью другой операции чтения. Когда сеанс подключения истечет, клиент будет отключен от сервера, а связанные часы будут удалены.
Теперь давайте поговорим о простом, и давайте поговорим о сложной части.
Несколько особенностей, которые нужно понять в первую очередь:
- One-time triggerВремя просмотра будет активировано только один раз.Если узел снова изменится, если часы не были сброшены ранее, вы получите уведомление;
- Sent to ClientПри изменении состояния объекта наблюдения будет срабатывать событие, соответствующее наблюдению за этим объектом. Событие наблюдения будет отправлено клиенту асинхронно, а ZooKeeper предоставляет механизм наблюдения.Гарантия заказа.
- The data for which the watch was setИнформация о данных, отправляемая клиенту, на самом деле является типом мониторинга ваших часов, см. ниже.
Часы зоопарка делятся на два типа:Часы с данными и детские часы. То есть вы можете установить часы для данных узла, а также можете установить часы для дочернего узла.
Взгляните на Java-клиент Zookeeper.Zkclient
Код для установки часов в:
// listener 监听器
// path 节点路径
// 子节点监听器
private List<String> addTargetChildListener(String path, IZkChildListener listener) {
return client.subscribeChildChanges(path, listener);
}
// 节点数据的监听器
public void addChildDataListener(String path, IZkDataListener listener) {
try {
// 递归创建节点
client.subscribeDataChanges(path, listener);
} catch (ZkNodeExistsException e) {
}
}
Как разработчик, вы должны знать, какие действия на узле мониторинга вызовут установленные вами часы.
- Успешная операция setData вызовет отслеживание данных Znode.
- Успешная операция создания вызовет наблюдение за данными Znode и наблюдение за дочерним узлом.
- Успешная операция удаления вызовет наблюдение за данными Znode и наблюдение за дочерним узлом.
Давайте посмотрим на интерфейс прослушивателя данных в ZkClient.IZkDataListener
public interface IZkDataListener {
// 监控节点数据更新的时候会触发 这段逻辑
public void handleDataChange(String dataPath, Object data) throws Exception;
// 监控节点被删除的时候会触发 这段逻辑
public void handleDataDeleted(String dataPath) throws Exception;
}
Давайте посмотрим на интерфейс слушателя дочернего узла в ZkClient.IZkChildListener
public interface IZkChildListener {
/**
* Called when the children of the given path changed.
* 监控节点的子节点列表改变时会触发这段逻辑
*
* @param parentPath
* The parent path
* @param currentChilds
* The children or null if the root node (parent path) was deleted.
* @throws Exception
*/
public void handleChildChange(String parentPath, List<String> currentChilds) throws Exception;
}
На самом деле, когда вы видите это, вы можете подумать, что Zookeeper можно использовать как распределенный центр конфигурации, но вам нужно расширить его логику, чтобы асинхронно оповещать узлы после изменения данных и обновлять вашу конфигурацию. Связанные демонстрации будут обновлены в последующих главах.
Подробную информацию о часах см. во введении на официальном сайте:
ZooKeeper Watches
6. Резюме
Содержание этой главы является началом серии статей о Zookeeper, в ней представлены несколько основных концепций Zookeeper и приведены соответствующие примеры для облегчения понимания.
Теперь вернемся назад и посмотрим на возможности Zookeeper:
① Последовательная согласованность Запросы на транзакции, инициированные одним и тем же клиентом, в конечном итоге будут применяться к ZooKeeper в строгом соответствии с порядком, в котором они были инициированы.
② Атомарность Результаты всех запросов транзакций применяются одинаково ко всем машинам в кластере, то есть либо все кластеры во всем кластере успешно применили определенную транзакцию, либо ни один из них не был применен, и будет не исключено, что некоторые машины в кластере применили транзакцию, а другая часть не применила.
③ Один вид Независимо от того, к какому серверу ZooKeeper подключается клиент, он видит одну и ту же модель данных на стороне сервера.
④ Надежность Как только сервер успешно применит транзакцию и завершит ответ клиенту, изменения состояния сервера, вызванные транзакцией, будут сохранены до тех пор, пока другая транзакция не изменит его.
⑤ В режиме реального времени Обычно первая реакция людей на просмотр в режиме реального времени заключается в том, что после успешного применения транзакции клиент может немедленно прочитать последний статус данных после того, как транзакция была изменена с сервера. Здесь следует отметить, что ZooKeeper только гарантирует, что в течение определенного периода времени клиент в конечном итоге сможет прочитать последний статус данных с сервера.
В сегодняшнем содержаниипоследовательная согласованностьРеализуется ZXid, который уникален в глобальном масштабе и увеличивается последовательно.Запросы в одной сессии идут FIFO;надежностьОписание также можно понять с помощью сегодняшних знаний.Применение транзакции, изменение состояния сервера будут сохранены в виде Zxid, версии данных Znode, данных и пути к узлу. Как реализованы остальные возможности, следует понять после знакомства с кластером Zookeeper.
Эта статья основана на нескольких отличных статьях в Интернете и сочетает в себе некоторые мои собственные размышления и практику. Надеюсь, это поможет вам узнать о Zookeeper.
В следующей главе я расскажу о кластере Zookeeper,CAP
Практика теории в Zookeeper и как построить кластер Zookeeper.
Ссылаться на
[1] zookeeper.apache.org/doc/3.4.14…Официальная документация (настоятельно рекомендуется)
[2] Блог Woohoo.cn на.com/Солнце ждет использования/боится…Автор должен иметь относительно глубокое понимание официальных документов, я обнаружил, что контекст его статьи очень похож на официальный сайт. очень хорошо написано
[3] woo woo Краткое описание.com/afraid/ah 1721 Этот метод 6…Автор сделал простое для понимания общее введение в Zookeeper.
[4] www.w3cschool.cn/zookeeper/ w3cSchool tutorial