Topology RFC (v3.1)

2022-06-13
Yaroslav Dynnikov

Мы рассмотрим несколько сценариев работы с кластером. Все они основаны на одном и том же принципе, а сложность деплоя фактически зависит только от сложности самой топологии.


Кластер с минимальными усилиями

С минимальными, так с минимальными. Обязательных параметров у пикодаты нет совсем. Так что одноинстансовый кластер запускается командой

picodata run

Запускайте сколько хотите инстансов, кластер будет расти. Каждому инстансу придётся выделить рабочую директорию и listen адрес. Фактор репликации по умолчанию равен 1 — каждый инстанс образует отдельный репликасет.

picodata run --data-dir i1 --listen :3301
picodata run --data-dir i2 --listen :3302
picodata run --data-dir i3 --listen :3303

Q: Что, даже peer не надо указывать (для кластера из 3х)?
A: Да, по умолчанию --peer=127.0.0.1:3301, прям как дефолтный --listen

Несколько серверов

Когда локалхост покорён, самое время запустить пикодату на нескольких серверах. Предположим их два — 192.168.0.1 и 192.168.0.2. Запускаем:

На 192.168.0.1:

picodata run --listen 0.0.0.0 --advertise 192.168.0.1

На 192.168.0.2:

picodata run --listen 0.0.0.0 --advertise 192.168.0.2 --peer 192.168.0.1

Во-первых, вместо дефолтного 127.0.0.1 надо указать --listen=0.0.0.0. Порт указывать не обязательно (по умолчанию везде используется :3301), но для наглядности лучше использовать полноценный формат <HOST>:<PORT>.

Значение --listen не хранится в кластерной конфигурации. Поменять его можно на рестарте.

Во-вторых, надо дать инстансам возможность обнаружить друг друга. В параметре --peer указываем адрес одного соседа для дискавери. По дефолту --peer=127.0.0.1:3301. Параметр --peer ни на что, кроме дискавери, не влияет.

Параметр --advertise сообщает, по какому адресу остальные инстансы должны обращаться к данному. По умолчанию он определяется автоматически как <HOSTNAME>:<LISTEN_PORT>.

Значение --advertise анонсируется кластеру на старте инстанса. Его можно поменять при рестарте или в рантайме командой picodata set-advertise.

Питомцы против стада

Чтобы проще было отличать инстансы друг от друга, инстансам можно давать имена:

picodata run --instance-id barsik

Если имя не дать, оно будет сгенерировано автоматически в момент добавления в кластер. Имя инстанса персистится в снапшотах и не подлежит редактированию. Иметь в кластере два инстанса с одинаковым именем тоже запрещено — второй инстанс получит ошибку при добавлении. Тем не менее, имя можно переиспользовать, если предварительно выгнать инстанс командой picodata expel barsik.

Репликация и зоны доступности (failure domains)

Количество реплик настраивается параметром --init-replication-factor.
Этот параметр играет роль только в момент инициализации кластера. Бутстрап лидер записывает это значение в кластерную конфигурацию (replication-factor). В дальнейшем значение --init-replication-factor игнорируется.

Отредактировать фактор репликации, сохраненный в конфиге кластера, можно командой picodata set-replication-factor. Редактирование кластерного конфига сказывается только на новых добавляемых инстансах, но не затрагивает уже работающие.

Этот параметр составляет часть конфигурации кластера и обозначает желаемое количество реплик в каждом репликасет.е

При добавлении инстанса, фактор репликации будет записан в кластерную конфигурацию, но такой сценарий позволяет изменять аго только в сторону увеличения. Уменьшить фактор репликации можно командой picodata set-replication-factor, но опять же, с уже работающими инстансами ничего не произойдёт.

По мере усложнения топологии встаёт ещё один вопрос — как запретить пикодате объединять в репликасет инстансы из одного датацентра. Понятие датацентра здесь используется только как пример, на самом деле пикодата позволяет использовать любые удобные понятия — регион (eu-east), датацентр, стойка, сервер, или придумать свои обозначения (blue, green, yellow).

picodata run --replication-factor 2 --failure-domain region=us,zone=us-west-1

Добавление инстанса в репликасет происходит по следующим правилам:

  • Если в каком-то репликасете количество инстансов меньше необходимого фактора репликации, новый инстанс добавляется в него при условии, что их фейл домены отличаются.
  • Если подходящих репликасетов нет, пикодата создаёт новый репликасет.

Параметр --failure-domain играет роль только в момент добавления инстанса в кластер. Принадлежность инстанса репликасету впоследствии не меняется.

Как и параметр --advertise, значение failure-domain каждого инстанса можно редактировать

  • Либо перезапустив инстанс с новыми параметрами.
  • Либо в рантайме командой picodata set-failure-domain.

Добавляемый инстанс должен обладать тем же набором ключей, которые уже есть в кластере. Например, инстанс dc=msk не сможет присоединиться к кластеру с --failure-domain region=eu/us и вернёт ошибку.

Группы репликасетов

Иногда бывает так, что в разных репликасетах хочется использовать разный фактор репликации или ограничить размер хранимых данных. Классический пример — разделение кластера на стораджа и роутеры.

Это делается с помощью параметра --replicaset-group. По умолчанию инстансы добавляются в неявную группу "default", но пользователь может насоздавать сколько угодно новых, перечислив их в параметре --available-replicaset-groups.

export PICODATA_AVAILABLE_REPLICASET_GROUPS=\
"name=storage:replication-factor=3,"\
"name=router:storage-weight=0"

Теперь при запуске инстансов можно будет указывать

picodata run --replicaset-group router

Наличие групп не ограничивает пользователя в создании новых. Как и в случае с --replication-factor, новые группы можно добавлять вместе с добавлением новых инстансов.

Кейс: два датацентра по две реплики

Пикодата старается не объединять в один репликасет инстансы, у которых совпадает хотя бы один фейл домен. Но иногда это прямо таки необходимо. Чтобы ограничить пикодату в бесконечном создании репликасетов, можно воспользоваться флагом --max-replicaset-count (по умолчанию inf).

Как и --replication-factor, параметр --max-replicaset-count можно назначать разным для разных групп репликасетов.

Как и другие параметры, --max-replicaset-count редактируется в любой момент:

  • При добавлении нового инстанса
  • В рантайме командой picodata set-max-replicaset-count

Единственное, --max-replicaset-count нельзя сделать меньше существующего количества репликасетов.

Файлы конфигурации

Пикодата позволяет передавать параметры из трёх мест (в порядке возрастания приоритета):

  1. Файл конфига (yaml / toml)
  2. Переменные окружения PICODATA_<PARAM>=<VALUE>
  3. Аргументы командной строки --param value

Мы перечислили достаточно много разнобразных параметров, некоторые из которых достаточно развесистые. Пользуйтесь конфигами:

c1.toml
[[available-replicaset-groups]]:
name = "storage"
max-replicaset-count = 30
replication-factor = 4

[[available-replicaset-groups]]
name = "router"
storage-weight = 0

Ползучие воутеры (raft voter failover)

Все рафт ноды в кластере делятся на две роли - воутеры и лёрнеры. За консистентность отвечают только воутеры. Для коммита каждой транзакции требуется собрать кворум из N/2 + 1 воутеров. Лернеры в кворуме не участвуют.

Чтобы сохранить баланс между надёжностью кластера и беззаботностью его эксплуатации, пикодата обладает фишечкой — при смерти одного из воутеров (на которох держится кворум рафта и который терять очень не хочется) роль воутера автоматически передаётся одному из живых инстансов. Переключение происходит незаметно для пользователя.

Количество воутеров в кластере не настраивается и зависит только от общего количества инстансов. Если инстансов 1 или 2, воутер один. Если инстансов 3 или 4, то воутера три. Для кластеров от 5 инстансов и больше - пять воутеров.

Configuration reference

--cfg <path>
: Read configuration parameters from file (toml / yaml).
env: PICODATA_CFG
default: none

--data-dir
Here the instance persists all of its data.
env: PICODATA_DATA_DIR
default: .
--listen
Socket bind address.
env: PICODATA_LISTEN
default: localhost:3301
--peer <[host][:port]>
Address of other instance(s).
env: PICODATA_PEER
default: localhost:3301
--advertise <[host][:port]>
Address the other instances should use to connect to this instance.
env: PICODATA_ADVERTISE
default: %hostname%:%listen_port%
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
: Если %listen% == "0.0.0.0", то надо подставлять %hostname%. Сейчас дефолт всегда просто %listen%.
--cluster-id <name>
Name of the cluster. The instance will refuse to join the cluster with a different name.
env: PICODATA_CLUSTER_ID
default: demo
--instance-id <name>
Name of the instance.
env: PICODATA_INSTANCE_ID
default: i%raft_id%, e.g. i1, i42, etc.
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
: Надо придумать, как идентифицировать клиентов в батче, если айдишник генерится только при обработке запроса. Ответ - по адвертайзу.
--failure-domain <key=value,...>
Comma-separated list describing physical location of the server. Each domain is a key-value pair. Until max replicaset count is reached, picodata will never put two instances with a common failure domain in the same replicaset. Instead, new replicasets will e created. They'll be filled with other instances until desired replication factor is satisfied.
env: PICODATA_FAILURE_DOMAIN
default: none
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
: Объяснить правила "common failure domain".
--replicaset-group <name>
Name of the replicaset group. It's an error to run instance with a group changed.
env: PICODATA_REPLICASET_GROUP
default: default
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Зачем это? Без картинки, поясняющей архитектуру кластера, объяснить сложновато .
--init-replication-factor <number>
Total number of replicas (copies of data) for each replicaset in the current group.
env: PICODATA_INIT_REPLICATION_FACTOR
default: 1
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Учитывается только при создании группы. Потом игнорируется.
--init-storage-weight <number>
Proportional capacity of current instance. Common for each instance in the current group.
env: PICODATA_INIT_STORAGE_WEIGHT
default: 1
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Учитывается только при создании группы. Потом игнорируется.
--max-replicaset-count
Maximum number of replicasets in the current group.
env: PICODATA_MAX_REPLICASET_COUNT
default: don't modify
Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →
Если меньше текущего размера группы, то игнорируется. Если в текущей группе нет места, то ошибка. Если больше — настройка применяется к текущей группе репликасетов.