Skip to content

Latest commit

 

History

History
159 lines (149 loc) · 12.9 KB

File metadata and controls

159 lines (149 loc) · 12.9 KB

Лабораторная работа №4 - ZooKeeper 👨‍🌾

Задание

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

Установка и запуск

Для установки использовалась следующая команда: brew install zookeeper

Для запуска же: zkServer start

Изучение директории

Перейдем в директорию установки ZooKeeper и изучим содержимое директории.
В директории находятся следующие папки:

  • bin с исполняемыми файлами для запуска, остановки и взаимодействия с ZooKeeper,
  • conf с конфигурационными файлами,
  • contrib с инструментами для интеграции ZooKeeper в другие системы: rest, fuse, perl и python библиотеки,
  • dist-maven артефакты Maven,
  • docs в которой хранится документация,
  • recipes различные рецепты, помогающие решать задачи с использованием ZooKeeper (выбор лидера, блокировки, очереди),
  • src с исходным кодом и тестовыми скриптами.

Запуск интерактивной сессии ZooKeeper CLI, освоение команд

Для запуска интерактивной сессии ZooKeeper CLI используем скрипт zkCli. Следующая команда устанавливает подключение к ZooKeeper CLI сессии:

Подключение установлено. Для вывода всех возможных команд наберем help:
Далее последует изучение возможностей CLI интерфейса. Научимся добавлять и удалять разные типы узлов znode, считывать и записывать данные в znode из CLI, разбираться в управлении конфигурациями на базовых примерах. Находясь в консоли CLI введем команду ls /. В результе получим список узлов в корне иерархической структуры данных ZooKeeper. В данном случае выводится один узел. Аналогично можно изучать некорневые узлы. Выведем список дочерних узлов /zookeeper:


Теперь в корне создим свой узел /mynode с данными "first_version" следующей командой create /mynode 'first_version'. Проверяем, что в корне появился новый узел:


Изменим данные узла на "second_version":


Создадим два нумерованных (sequential) узла в качестве дочерних mynode:



Передав дополнительно флаг -s, мы указали, что создаваемый узел нумерованный. Этот способ позволяет создавать узлы с уникальными именами, по которым можно узнать порядок поступления запросов на сервер.
Пример. Принадлежность клиентов к группе.
Несмотря на то, что ZooKeeper используется, как правило, из программного кода, мы можем эмулировать простой сценарий мониторинга принадлежности клиентов к группе в CLI.
В данном примере в корне zookeeper файловой системы будет создан узел под именем mygroup. Затем несколько сессий CLI будут эмулировать клиентов, добавляющих себя в эту группу. Клиент будет добавлять эфимерный узел в mygroup иерархию. При закрытии сессии узел автоматически будет удаляться. Этот сценарий может применяться для реализации сервиса разрешения имён (DNS) узлов кластера. Каждый узел регистрирует себя под своим именем и сохраняет свой url или ip адрес. Узлы, которые временно недоступны или аварийно завершили работу, в списке отсутствуют. Таким образом директория хранит актуальный список работающих узлов с их адресами.
Внутри CLI сессии, создадим узел mygroup. Откроем две новых CLI консоли и в каждой создайте по дочернему узлу в mygroup и проверим, что grue и bleen являются членами группы mygroup:



Представим теперь, что одному из клиентов нужна информация о другом клиенте (к качестве клиентов могут выступать узлы кластера). Этот сценарий эмулируется получением информации командой get. Выберем консоль grue и обратимся к информации узла bleen.
Информацией, которая хранится в узле клиента может быть url адрес клиента, либо любая другая информация требуемая для работы распределённого приложения.
Теперь эмулируем аварийное отключение любого клиента. Нажмем сочетание клавиш Ctrl + D в одной из консолей, создавшей эфимерный узел.
Проверим, что соответствующий узел пропал из mygroup. Изменение списка дочерних узлов может произойти не сразу — от 2 до 20 tickTime, значение которого можно посмотреть в zoo.cfg.


Таким образом клиенты могут получать информацию о появлении и отключении других клиентов. В заключении удалим узел /mygroup.


Пример управления конфигурацией распределённого приложения

Хранение конфигурационной информации в ZooKeeper одно из наиболее популярных приложений. Мы будем эмулировать данную концепцию также с помощью CLI.
Использование ZooKeeper для хранения конфигурационной информации имеет два преимущества:

  • Новые клиенты могут узнавать конфигурацию кластера и определять свою роль самостоятельно,
  • Возможность подписки на обновление конфигурационных параметров. Это позволяет динамически реагировать на изменения в конфигурации во время выполнения, что необходимо в режиме работы 24/7.

Создадим в корне узел "myconfig", в задачу которого будет входить хранение конфигурации. В нашем случае узел будет хранить строку 'sheep_count=1'. Во всех случаях, когда конфигурационная информация нашего гипотетического распределённого приложения будет изменяться, мы будем обновлять znode строкой с новым значением. Другим клиентам распределённого приложения достаточно проверять хранимые в этом узле данные.
Откроем новую консоль и подключитесь к ZooKeeper. Данная консоль будет играть роль физического сервера, который ожидает получить оповещение в случае изменения конфигурационной информации, записанной в /myconfig znode.
Следующая команда устанавливает watch-триггер на узел:

get /myconfig -w true

Вернемся к первому терминалу и изменим значение myconfig:

set /myconfig 'sheep_count=2'

Во втором терминале должно появиться оповещение об изменении данных!


Триггер сбрасывается после одного срабатывания, а значит его придётся 'взводить' каждый раз заново. Как правило, в приложении, в логике обработчика события присутствует такая процедура.

Удалим узел /myconfigи проверим, что эта команда выполнилась.

Разработка, запуск и проверка работы приложения

  1. Решить проблему обедающих философов
    Результат выполнения :
Philosopher 2 is going to eat
Philosopher 1 is going to eat
Philosopher 0 is going to eat
Philosopher 0 picked up the left fork
Philosopher 0 picked up the right fork
Philosopher 0 put the right fork
Philosopher 1 picked up the left fork
Philosopher 1 picked up the right fork
Philosopher 0 put the loft fork and finished eating
Philosopher 0 is thinking
Philosopher 2 picked up the left fork
Philosopher 1 put the right fork
Philosopher 1 put the loft fork and finished eating
Philosopher 2 picked up the right fork
Philosopher 1 is thinking
Philosopher 0 is going to eat
Philosopher 1 is going to eat
Philosopher 0 picked up the left fork
Philosopher 2 put the right fork
Philosopher 0 picked up the right fork
Philosopher 2 put the loft fork and finished eating
Philosopher 2 is thinking
Philosopher 1 picked up the left fork
Philosopher 0 put the right fork
Philosopher 1 picked up the right fork
Philosopher 0 put the loft fork and finished eating
Philosopher 0 is thinking
Philosopher 1 put the right fork
Philosopher 1 put the loft fork and finished eating
Philosopher 1 is thinking
Philosopher 2 is going to eat
Philosopher 2 picked up the left fork
Philosopher 2 picked up the right fork
Philosopher 2 put the right fork
Philosopher 2 put the loft fork and finished eating
Philosopher 2 is thinking

Process finished with exit code 0
  1. Реализовать двуфазный коммит протокол для high-available регистр
    Результат выполнения:
Waiting others clients: []
Client 0 request commit
Client 1 request abort
Client 4 request abort
Client 3 request abort
Client 2 request abort
Check clients
Client 0 do abort
Client 1 do abort
Client 2 do abort
Client 3 do abort
Client 4 do abort
Waiting others clients: []

Process finished with exit code 0