Модуль membership

Модуль membership

Этот модуль представляет собой библиотеку membership для Tarantool’а на основе протокола gossip.

Эта библиотека создает сеть из нескольких экземпляров Tarantool. Сеть сама контролирует себя, помогает участникам обнаружить всех остальных в группе и получать уведомления об изменениях своего статуса с низкой задержкой. Модуль основан на концепциях из Consul или, точнее, алгоритма SWIM.

Модуль membership работает по протоколу UDP и может производить операции даже до инициализации box.cfg.

Структура членов данных

Члены-данные представлены в виде таблиц со следующими полями:

  • uri (строка) – это унифицированный идентификатор ресурса.

  • status (строка) – это строка, которая принимает одно из следующих значений.

    • alive: член группы, который отвечает на сообщения проверки связи, работоспособен в статусе alive.

    • suspect: если какой-либо член группы не может получить ответ от какого-либо другого участника, первый член группы просит трех других активных членов группы в статусе alive отправить сообщение проверки связи соответствующему участнику. Если ответа нет, последний получает статус сомнительного, то есть suspect.

    • dead: член группы в статусе suspect получает статус вышедшего из строя dead по истечении времени ожидания.

    • left: член группы получает статус выбывшего left после выполнения функции leave().

      Примечание

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

  • incarnation (число) – это значение, которое увеличивается каждый раз, когда экземпляр получает статус suspect, dead или обновляет полезную нагрузку.

  • payload (таблица) – это вспомогательные данные, которыми могут воспользоваться различные модули.

  • timestamp (число) – это значение fiber.time64(), которое:

    • соответствует последнему обновлению параметра status или incarnation;
    • всегда локально;
    • не зависит от настроек часов других членов группы.

Ниже приведен пример таблицы:

tarantool> membership.myself()
---
uri: localhost:33001
status: alive
incarnation: 1
payload:
    uuid: 2d00c500-2570-4019-bfcc-ab25e5096b73
timestamp: 1522427330993752
...

Справочник по API

Ниже приведен список простых функций, функций шифрования, подписки и параметры модуля membership.

Имя Назначение
Простые функции
init(advertise_host, port) Инициализация модуля membership.
myself() Получение структуры данных текущего экземпляра.
get_member(uri) Получение структуры данных для указанного URI.
members() Получение таблицы со всеми членами группы, известными текущему экземпляру.
pairs() Сокращение для pairs(membership.members()).
add_member(uri) Добавление члена в группу.
probe_uri(uri) Проверка принадлежности члена к группе.
broadcast() Обнаружение участников в локальной сети путем отправки широковещательного сообщения UDP.
set_payload(key, value) Обновление myself().payload и распространение информации.
leave() Корректное исключение из группы.
is_encrypted() Проверка, включено ли шифрование.
Функции шифрования
set_encryption_key(key) Установка ключа для низкоуровневого шифрования сообщений.
get_encryption_key() Получение используемого ключа шифрования.
Функции подписки
subscribe() Подписка на обновления членов таблицы.
unsubscribe() Удаление подписки.
Параметры
PROTOCOL_PERIOD_SECONDS Время отправки сообщений проверки связи напрямую.
ACK_TIMEOUT_SECONDS Время ожидания сообщения подтверждения.
ANTI_ENTROPY_PERIOD_SECONDS Период синхронизации во избежание энтропии.
SUSPECT_TIMEOUT_SECONDS Время ожидания, чтобы перевести члена группы из статуса suspect в dead.
NUM_FAILURE_DETECTION_SUBGROUPS Число членов группы, которые отправляют сообщения проверки связи члену группы в статусе suspect.

Простые функции:

membership.init(advertise_host, port)

Инициализация модуля membership. Привязывает UDP-сокет к 0.0.0.0:<port>, задает значение параметра advertise_uri = <advertise_host>:<port> (передаваемый хост, порт) и значение параметра incarnation = 1.

Функцию init() можно вызвать несколько раз, старый сокет будет закрыт, откроется новый сокет.

Если значение параметра advertise_uri изменится во время очередного выполнения init(), старый URI считается недоступным со статусом DEAD. Чтобы корректно исключить члена из группы, используйте функцию leave().

Параметры:
  • advertise_host (string) – имя хоста или IP-адрес, передаваемый другим членам группы
  • port (number) – привязываемый UDP-порт
возвращает:

true (правда)

тип возвращаемого значения:
 

boolean (логический)

вызывает:

подключенный сокет, если нет ошибки

membership.myself()
возвращает:структура данных члена группы для текущего экземпляра.
тип возвращаемого значения:
 таблица
membership.get_member(uri)
Параметры:
  • uri (string) – advertise_uri для указанного члена группы
возвращает:

структура данных экземпляра с указанным URI.

тип возвращаемого значения:
 

таблица

membership.members()

Получение всех членов группы, известных текущему экземпляру.

Редактирование этой таблицы ни на что не вляет.

возвращает:таблица с URI в качестве ключей и структурой данных члена группы в качестве значений.
тип возвращаемого значения:
 таблица
membership.pairs()

Сокращение для pairs(membership.members()).

возвращает:Lua-итератор

Можно использовать следующим образом:

for uri, member in memberhip.pairs()
  -- что-то сделать
end
membership.add_member(uri)

Добавление в группу члена с указанным URI и передача информации об этом событии другим членам группы. Достаточно добавить члена группы в один экземпляр, так как все остальные экземпляры в группе со временем получат информацию об этом. Не имеет значения, кто кого добавляет.

Параметры:
  • uri (string) – параметр advertise_uri добавляемого члена группы
возвращает:

true (правда) или нулевое значение nil в случае ошибки

тип возвращаемого значения:
 

boolean (логический)

вызывает:

ошибка анализа, если URI нельзя проанализировать

membership.probe_uri(uri)

Отправка сообщения члену группы, чтобы убедиться, что он включен в группу. Если экземпляр активен со статусом alive, но не включен в группу, происходит его добавление. Если он уже включен в группу, ничего не происходит.

Параметры:
  • uri (string) – параметр advertise_uri члена группы, которому отправляются сообщения проверки связи
возвращает:

true (правда), если ответ возвращается в течение 0.2 секунды, в остальных случаях no response (нет ответа)

тип возвращаемого значения:
 

boolean (логический)

вызывает:

ping was not sent (сообщение проверки связи не отправлено), если имя хоста не разрешено

membership.broadcast()

Обнаружение членов группы в локальной сети путем отправки широковещательного сообщения UDP во все сети, обнаруженные с помощью вызова getifaddrs() на языке C.

возвращает:true (правда), если сообщение отправлено, false (ложь), если getaddrinfo() не выполнена.
тип возвращаемого значения:
 boolean (логический)
membership.set_payload(key, value)

Обновление myself().payload и распространение соответствующей информации вместе со статусом члена группы.

Увеличивает значение параметра incarnation.

Параметры:
  • key (string) – ключ, задаваемый в таблице payload
  • value – дополнительные данные
возвращает:

true (правда)

тип возвращаемого значения:
 

boolean (логический)

membership.leave()

Корректное исключение из группы membership. Узел получает статус выбывшего left, другие члены группы не будут пытаться снова подключить его.

возвращает:true (правда)
тип возвращаемого значения:
 boolean (логический)
membership.is_encrypted()
возвращает:true (правда), если шифрование включено, false в противном случае.
тип возвращаемого значения:
 boolean (логический)

Функции шифрования:

membership.set_encryption_key(key)

Установка ключа, который используется для низкоуровневого шифрования сообщений. Ключ автоматически обрезается или дополняется до 32 байтов. Если значения ключа key нулевое nil, шифрование будет отключено.

Модуль Tarantool crypto.cipher.aes256.cbc занимается шифрованием.

Чтобы обеспечить правильную связь, все члены группы должны быть настроены на использование одного и того же ключа шифрования. В противном случае члены группы получат статус либо dead, либо non-decryptable (невозможно расшифровать).

Параметры:
  • key (string) – ключ шифрования
возвращает:

nil.

membership.get_encryption_key()

Получение используемого ключа шифрования.

возвращает:ключ шифрования или нулевое значение nil, если шифрование отключено.
тип возвращаемого значения:
 строка

Функции подписки:

membership.subscribe()

Подписка на обновления членов таблицы.

возвращает:объект fiber.cond, который передается при каждом изменении таблицы.
тип возвращаемого значения:
 объект
membership.unsubscribe(cond)

Удаление подписки на cond, получаемый с помощью функции subscribe().

Достоверность cond не проверяется.

Параметры:
  • cond – объект fiber.cond, получаемый с помощью функции subscribe()
возвращает:

nil.

Ниже приведен перечень параметров membership. Их можно задать следующим образом:

options = require('membership.options')
options.<параметр> = <значение>
options.PROTOCOL_PERIOD_SECONDS

Период отправки сообщение проверки связи напрямую. Обозначается как T' в протоколе SWIM.

options.ACK_TIMEOUT_SECONDS

Время ожидания сообщения подтверждения после отправки сообщения проверки связи. Если ответ запаздывает, вызывается алгоритм косвенной проверки связи.

options.ANTI_ENTROPY_PERIOD_SECONDS

Период выполнения алгоритма синхронизации во избежание энтропии из протокола SWIM.

options.SUSPECT_TIMEOUT_SECONDS

Время ожидания, чтобы перевести члена группы из статуса suspect в dead.

options.NUM_FAILURE_DETECTION_SUBGROUPS

Число членов группы, которые пытаются отправить сообщения проверки связи члену группы в статусе suspect. Обозначается как k в протоколе SWIM.