Zookeeper

как не пустить двух белок в одно дупло

Докладчик: ...я...

Небольшая проверка начальных знаний.

Что такое zookeeper?

Что такое мьютекс?

Что такое сервер?

Apache Zookeeper

  • Лицензия: Apache License v2.0
  • Текущая стабильная версия: 3.5
  • Версия 3.0 доступна с 2008г. 

Apache Zookeeper

Apache Zookeeper: система для синхронизации работы распределенных приложений .

Apache Zookeeper

Apache Zookeeper: система для синхронизации работы распределенных приложений .

  • Сиcтема асинхронной передачи сообщений и бродкастинга событий.
  • Распределенные локи и выборы "головы" децентрализованного кластера машин.
  • Система хранения актуальных конфигов.

Apache Zookeeper

Apache Zookeeper: система для синхронизации работы распределенных приложений .

  • Сиcтема асинхронной передачи сообщений и бродкастинга событий.
  • Распределенные локи и выборы "головы" децентрализованного кластера машин.
  • Система хранения актуальных конфигов.
  • На что еще хватит вашей фантазии...

О масштабах

Zookeeper

Zookeeper

Zookeeper

Server Side:

   /
   |-node1
   |-node2
   |---subnode1
   |---subnode2
   |-node3
   |---subnode
   |-----subsubnode
   |-zookeeper

Zookeeper

Server Side:

   /
   |-node1
   |-node2
   |---subnode1
   |---subnode2
   |-node3
   |---subnode
   |-----subsubnode
   |-zookeeper

Operations

  • create
  • delete
  • exists
  • get_data
  • set_data
  • get_children
  • sync

Zookeeper

Demo 1.0

Способ поднять простой "дефолтный" сервер zookeeper

Zookeeper

Garantees

Zookeeper

Garantees

  • Sequential Consistency: все обновления будут применены в том порядке, в котором клиент их отправил.

Zookeeper

Garantees

  • Sequential Consistency: все обновления будут применены в том порядке, в котором клиент их отправил.
  • Atomicity: Обновления либо будут применены полностью, либо не будут применены вообще. 

Zookeeper

Garantees

  • Sequential Consistency: все обновления будут применены в том порядке, в котором клиент их отправил.
  • Atomicity: Обновления либо будут применены полностью, либо не будут применены вообще. 
  • Single System Image: Вне зависимости от сервера, к которому подключен клиент, клиенты будут видеть одно и то же состояние.

Zookeeper

Garantees

  • Sequential Consistency: все обновления будут применены в том порядке, в котором клиент их отправил.
  • Atomicity: Обновления либо будут применены полностью, либо не будут применены вообще. 
  • Single System Image: Вне зависимости от сервера, к которому подключен клиент, клиенты будут видеть одно и то же состояние.
  • Reliability: Примененные изменения сохранятся пока не будут переписаны.

Zookeeper

Garantees

  • Sequential Consistency: все обновления будут применены в том порядке, в котором клиент их отправил.
  • Atomicity: Обновления либо будут применены полностью, либо не будут применены вообще. 
  • Single System Image: Вне зависимости от сервера, к которому подключен клиент, клиенты будут видеть одно и то же состояние.
  • Reliability: Примененные изменения сохранятся пока не будут переписаны.
  • Timelines: Ответы всегда "последней свежести"

Задача:

Сделать стабильный сервис, доступный 24/7 

Задача:

Сделать стабильный сервис, доступный 24/7 

Задача:

Сделать стабильный сервис, доступный 24/7 

Задача:

Сделать стабильный сервис, доступный 24/7 

Задача:

Сделать стабильный сервис, доступный 24/7 

Задача:

Сделать стабильный сервис, доступный 24/7 

Задача:

Сделать стабильный сервис, доступный 24/7 

Zookeeper

Примитивная идея лока

Zookeeper

Примитивная идея лока

  • Создадим нод. Если удалось - лок взят.

  • Если неудалось - ждем случайный промежуток времени и пробуем снова.

  • Удаление нода - освобождение лока

Zookeeper

Demo 1.1

Клиентская сторона

Zookeeper

Реакция на потерю соединения

Zookeeper

Реакция на потерю соединения

ZNode

Persistent Node

Ephemeral Node

Zookeeper

Demo 2.0

Клиентская сторона

Zookeeper

Чем примитивный лок примитивен?

Zookeeper

Чем примитивный лок примитивен?

  • Время простоя: лок может освободиться сразу после нашего запроса, но мы вынуждены ждать по алгоритму.

Zookeeper

Чем примитивный лок примитивен?

  • Время простоя: лок может освободиться сразу после нашего запроса, но мы вынуждены ждать по алгоритму.
  • Загрузка серверов: мы должны посылать запросы постоянно без какой-либо гарантии получить лок.

Zookeeper

Чем примитивный лок примитивен?

  • Время простоя: лок может освободиться сразу после нашего запроса, но мы вынуждены ждать по алгоритму.
  • Загрузка серверов: мы должны посылать запросы постоянно без какой-либо гарантии получить лок.
  • С ненулевой вероятностью сервер, запросивыший лок на загруженной системе, не получит его в течении любого заданного конечного времени.

Zookeeper

Чем примитивный лок примитивен?

  • Время простоя: лок может освободиться сразу после нашего запроса, но мы вынуждены ждать по алгоритму.
  • Загрузка серверов: мы должны посылать запросы постоянно без какой-либо гарантии получить лок.
  • С ненулевой вероятностью сервер, запросивыший лок на загруженной системе, не получит его в течении любого заданного конечного времени.
  • Передавать штатную информацию через исключение - это просто капец дизайнерская фантазия...

Zookeeper

Коллбеки (Watchers)

Zookeeper

Коллбеки (Watchers)

Коллбеки можно повесить при операциях чтения

(getData, getChildren, exists)

Zookeeper

Коллбеки (Watchers)

Коллбеки можно повесить при операциях чтения

(getData, getChildren, exists)

Create Delete Change Child
exists
getData
getChildren

Одноразовый вызов при:

Zookeeper

Коллбеки (Watchers)

Watchers ordering guarantee: 

Клиент никогда не увидит измененные данные прежде, чем ему придет уведомление об изменении данных

Create Delete Change Child
exists
getData
getChildren

Одноразовый вызов при:

Zookeeper

Sequence Nodes

Zookeeper

Sequence Nodes

String res = zk.create("/path/to/node/prefix-" // Node path 
                       , new byte[16] // Node data
                       , Ids.OPEN_ACL_UNSAFE // Authorization 
                       , CreateMode.EPHEMERAL_SEQUENTIAL // Mode
                       );

Zookeeper

Sequence Nodes

String res = zk.create("/path/to/node/prefix-" // Node path 
                       , new byte[16] // Node data
                       , Ids.OPEN_ACL_UNSAFE // Authorization 
                       , CreateMode.EPHEMERAL_SEQUENTIAL // Mode
                       );
res; // "/path/to/node/prefix-0000000001"

Zookeeper

lock, вторая версия

Zookeeper

lock, вторая версия

  • Локом является нод с детьми. 

Node

prefix-001

prefix-002

Zookeeper

lock, вторая версия

  • Локом является нод с детьми. 
  • Попыткой залочить является создание потомка нода со следующим номером.

Node

prefix-001

prefix-002

prefix-003

Zookeeper

lock, вторая версия

  • Локом является нод с детьми. 
  • Попыткой залочить является создание потомка нода со следующим номером.
  • Процессом, залочившим нод считается процесс, создавший потомка нода с наименьшим номером. 

Node

001

002

003

Zookeeper

lock, вторая версия

  • Локом является нод с детьми. 
  • Попыткой залочить является создание потомка нода со следующим номером.
  • Процессом, залочившим нод считается процесс, создавший потомка нода с наименьшим номером. 
  • Процесс, номер потомка которого не последний, дожидается, пока он станет последним.

Zookeeper

lock, вторая версия

Demo 3

Zookeeper

lock, вторая версия

Недостатки

Zookeeper

lock, вторая версия

Недостатки

  • Масштабы (herd effect): Удаление потомка затрагивает ровно один сторонний процесс, однако уведомляются об этом все.

Zookeeper

lock, вторая версия

Недостатки

  • Масштабы (herd effect): Удаление потомка затрагивает ровно один сторонний процесс, однако уведомляются об этом все.
  • Гарантия атомарности операций над нодами не распространяется на то, что происходит после. В частности метод create может создать нод, но упасть на попытке отправить имя (!). Нод при этом будет создан.

Zookeeper

lock, версия третья

Zookeeper

lock, версия третья

  • Локом является нод с детьми. 
  • Попыткой залочить является создание потомка нода со следующим номером.
  • Процессом, залочившим нод считается процесс, создавший потомка нода с наименьшим номером. 
  • Процесс, номер потомка которого не последний, дожидается, пока он станет последним.

Zookeeper

lock, версия третья

Действия после создания нового потомка

Zookeeper

lock, версия третья

  1. Возьмем список потомков (без вотчера).

Действия после создания нового потомка

Zookeeper

lock, версия третья

  1. Возьмем список потомков (без вотчера).
  2. Если созданный нами потомок первый по номеру - процесс заканчивается, лок наш.

Действия после создания нового потомка

Zookeeper

lock, версия третья

  1. Возьмем список потомков (без вотчера).
  2. Если созданный нами потомок первый по номеру - процесс заканчивается, лок наш.
  3. Если нет, вызываем метод exists для ближайшего из предшествующих потомков выставив вотчер.

Действия после создания нового потомка

001

002

003

Zookeeper

lock, версия третья

  1. Возьмем список потомков (без вотчера).
  2. Если созданный нами потомок первый по номеру - процесс заканчивается, лок наш.
  3. Если нет, вызываем метод exists для ближайшего из предшествующих потомков выставив вотчер.
  4. Если метод вернул false - процесс заканчивается, возвращаемся к пункту 1. Если нет - после прихода коллбека возвращаемся к пункту 1.

Действия после создания нового потомка

Zookeeper

lock, версия третья

Demo 4 не будет.

Не нашел нормального способа продемонстрировать herd effect.

Zookeeper

lock: как найти своих потомков

Пропал Ребенок

  • Был создан на сервере зукипера по адресу localhost:3661 в 21:33 десятого января.
  • На момент выхода содержал ровно 16 байт информации.
  • Имя начинается на "prefix-"

Zookeeper

lock: как найти своих потомков

В имени потомка должен содержаться уникальный идентификатор

Zookeeper

lock: как найти своих потомков

В имени потомка должен содержаться уникальный идентификатор

  • GUID

Zookeeper

lock: как найти своих потомков

В имени потомка должен содержаться уникальный идентификатор

  • GUID
  • Session ID

Zookeeper

lock, версия третья

Demo 4.1 тоже не будет.

Не нашел как стабильно воспроизвести ошибку с возвратом имени на сервере.

Zookeeper

Вопросы, которые у вас назрели, но которые я просил не задавать.

Zookeeper

Вопросы, которые у вас назрели, но которые я просил не задавать.

На кой черт так мучаться? Гуглим Делаем любую реализацию lockByName и вешаем на простейший веб-сервис.

public class KeyedReentrantLock<K> {
    private ConcurrentMap<K, ReentrantLock> lockMap = new ConcurrentHashMap<K, ReentrantLock>();
    public void lock(K key) {
        ReentrantLock oldLock = lockMap.get(key);
        if (oldLock != null && oldLock.isHeldByCurrentThread()){
            // increase lock count and return.
            oldLock.lock();
            return;
        }
        ReentrantLock newLock = new ReentrantLock();
        newLock.lock();
        while ((oldLock = lockMap.putIfAbsent(key, newLock)) != null){
            // wait for the old lock to be released;
            oldLock.lock();
            oldLock.unlock();
        }
        return;
    }
    public void unlock(K key){
        ReentrantLock lock = lockMap.get(key);
        if (lock == null) throw new IllegalMonitorStateException("There was no lock for this key!");
        if (lock.getHoldCount() == 1){
            lockMap.remove(key);
        }
        lock.unlock();
    }
}

Zookeeper

На кой черт так мучаться? Гуглим Делаем любую реализацию lockByName и вешаем на простейший веб-сервис.

Zookeeper

На кой черт так мучаться? Гуглим Делаем любую реализацию lockByName и вешаем на простейший веб-сервис.

Zookeeper

На кой черт так мучаться? Гуглим Делаем любую реализацию lockByName и вешаем на простейший веб-сервис.

Zookeeper

На кой черт так мучаться? Гуглим Делаем любую реализацию lockByName и вешаем на простейший веб-сервис.

Zookeeper

На кой черт так мучаться? Гуглим Делаем любую реализацию lockByName и вешаем на простейший веб-сервис.

Demo 5.0

Zookeeper

На кой черт так мучаться? Гуглим Делаем любую реализацию lockByName и вешаем на простейший веб-сервис.

Demo 5.1

Интерактивное....

Zookeeper

Вопросы, которые у вас назрели, но которые я просил не задавать.

Zookeeper

Вопросы, которые у вас назрели, но которые я просил не задавать.

Если этот способ лока такой "стандартный", почему никто не написал сразу лок?

Zookeeper

Вопросы, которые у вас назрели, но которые я просил не задавать.

Если этот способ лока такой "стандартный", почему никто не написал сразу лок?

$ ls ./zookeeper/recipes/lock/src/java/org/apache/zookeeper/recipes/lock
LockListener.java  ProtocolSupport.java  WriteLock.java  ZNodeName.java  ZooKeeperOperation.java

$ ls ./zookeeper/recipes/
election  lock  queue

Zookeeper

Алсо

Zookeeper

Алсо

] get /javann_demo_three

cZxid = 0x2
ctime = Mon Jan 25 15:58:01 MSK 2016
mZxid = 0x2
mtime = Mon Jan 25 15:58:01 MSK 2016
pZxid = 0x500000002
cversion = 80
dataVersion = 0
aclVersion = 0
ephemeralOwner = 0x0
dataLength = 16
numChildren = 0

Куча дополнительной инфы о ноде

Zookeeper

Алсо

Кастомная настройка серверов...

Zookeeper

Алсо

Кастомная настройка серверов...

ACL: настройки доступа "из коробки"

Zookeeper

Алсо

Кастомная настройка серверов...

ACL: настройки доступа "из коробки"

Качественная система логирования

Zookeeper

Алсо

групповые выборы

(иерархические сервера)

this

Прочая инфа

  • Ник: Cadovvl
  • Мыло: pavelandreevith@gmail.com
  • Исходники примеров: https://github.com/Cadovvl/zookeeper_talk_demos
  • Где читать про zookeeper: https://zookeeper.apache.org/
  • Слава JavaNN!
  • Слава линуксу!

Zookeeper

By Cadovvl

Zookeeper

  • 669