Skip to content
Snippets Groups Projects
Commit e720fa4a authored by Alexander Tolstoy's avatar Alexander Tolstoy
Browse files

docs: review topology.md

parent 27dedfbe
No related branches found
No related tags found
1 merge request!140docs: review topology.md
Pipeline #6944 passed
......@@ -8,21 +8,21 @@ tags: Picodata, RFC
*2022-06-13*
*Yaroslav Dynnikov*
Мы рассмотрим несколько сценариев работы с кластером. Все они основаны на одном и том же принципе, а сложность деплоя фактически зависит только от сложности самой топологии.
В данном документе рассматриваются различные сценарии работы с кластером. Все они основаны на одном и том же принципе: запуске и объединении отдельных экземпляров Picodata в распределенный кластер. При этом сложность развертывания и поддержания работоспособности кластера зависит только от сложности его топологии.
[TOC]
---
## Кластер с минимальными усилиями
## Минимальный вариант кластера
С минимальными, так с минимальными. Обязательных параметров у пикодаты нет совсем. Так что одноинстансовый кластер запускается командой
Picodata может создать кластер, состоящий всего из одного экземпляра/инстанса. Обязательных параметров у него нет, что позволяет свести запуск к выполнению всего одной простой команды:
```
picodata run
```
Запускайте сколько хотите инстансов, кластер будет расти. Каждому инстансу придётся выделить рабочую директорию и `listen` адрес. Фактор репликации по умолчанию равен 1 — каждый инстанс образует отдельный репликасет.
Можно добавлять сколько угодно последующих инcтансов — все они будут подключаться к этому кластеру. Каждому интансу следует задать отдельную рабочую директорию (параметр `--data-dir`), а также указать адрес и порт для приема соединений (параметр `--listen`) в формате `<HOST>:<PORT>`. Фактор репликации по умолчанию равен 1 — каждый инстанс образует отдельный репликасет. Если для `--listen` указать только порт, то будет использован IP-адрес по умолчанию (127.0.0.1):
```
picodata run --data-dir i1 --listen :3301
......@@ -30,13 +30,13 @@ 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`
> Q: Нужно ли для небольшого кластера указывать параметр `--peer`?
> A: Это не обязательно, т.к. по умолчанию `--peer` имеет такое же значение по умолчанию как и `--listen`: _127.0.0.1:3301_.
## Несколько серверов
## Кластер на нескольких серверах
Когда локалхост покорён, самое время запустить пикодату на нескольких серверах. Предположим их два `192.168.0.1` и `192.168.0.2`. Запускаем:
Выше был показан запуск Picodata на одном сервере, что удобно для тестирования и отладки, но не отражает сценариев полноценного использования кластера. Поэтому пора запустить Picodata на нескольких серверах. Предположим, что их два: `192.168.0.1` и `192.168.0.2`. Порядок запуска будет таким:
На `192.168.0.1`:
```shell
......@@ -47,39 +47,40 @@ picodata run --listen 0.0.0.0 --advertise 192.168.0.1
```shell
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` вместо стандартного значения `127.0.0.1` надо указать `0.0.0.0`. Порт указывать не обязательно (по умолчанию везде используется `:3301`).
Значение `--listen` не хранится в кластерной конфигурации. Поменять его можно на рестарте.
Значение параметра `--listen` не хранится в кластерной конфигурации и может меняться при перезапуске инстанса.
Во-вторых, надо дать инстансам возможность обнаружить друг друга. В параметре `--peer` указываем адрес одного соседа для дискавери. По дефолту `--peer=127.0.0.1:3301`. Параметр `--peer` ни на что, кроме дискавери, не влияет.
Во-вторых, надо дать инстансам возможность обнаружить друг друга для того чтобы механизм [discovery](discovery.md) правильно собрал все найденные экземпляры Picodata в один кластер. Для этого в параметре `--peer` нужно указать адрес какого-либо соседнего инстанса. По умолчанию значение параметра `--peer` установлено в `127.0.0.1:3301`. Параметр `--peer` не влияет больше ни на что, кроме механизма обнаружения других инстансов.
Параметр `--advertise` сообщает, по какому адресу остальные инстансы должны обращаться к данному. По умолчанию он определяется автоматически как `<HOSTNAME>:<LISTEN_PORT>`.
Параметр `--advertise` сообщает, по какому адресу остальные инстансы должны обращаться к текущему инстансу. По умолчанию он определяется автоматически как `<HOSTNAME>:<LISTEN_PORT>`.
Значение `--advertise` анонсируется кластеру на старте инстанса. Его можно поменять при рестарте или в рантайме командой `picodata set-advertise`.
Значение параметра `--advertise` анонсируется кластеру при запуске инстанса. Его можно поменять при перезапуске инстанса или в процессе его работы командой `picodata set-advertise`.
## Питомцы против стада
Чтобы проще было отличать инстансы друг от друга, инстансам можно давать имена:
Чтобы проще было отличать инстансы друг от друга, им можно давать имена:
```
picodata run --instance-id barsik
```
Если имя не дать, оно будет сгенерировано автоматически в момент добавления в кластер. Имя инстанса персистится в снапшотах и не подлежит редактированию. Иметь в кластере два инстанса с одинаковым именем тоже запрещено — второй инстанс получит ошибку при добавлении. Тем не менее, имя можно переиспользовать, если предварительно выгнать инстанс командой `picodata expel barsik`.
Если имя не дать, то оно будет сгенерировано автоматически в момент добавления в кластер. Имя инстанса задается один раз и не может быть изменено в дальнейшем (например, оно постоянно сохраняется в снапшотах инстанса). В кластере нельзя иметь два инстанса с одинаковым именем — второй инстанс сразу после запуска получит ошибку при добавлении в кластер. Тем не менее, имя можно повторно использовать если предварительно исключить первый инстанс с таким именем из кластера. Это делается командой `picodata expel barsik`.
## Репликация и зоны доступности (failure domains)
Количество реплик настраивается параметром `--init-replication-factor`.
Этот параметр играет роль только в момент инициализации кластера. Бутстрап лидер записывает это значение в кластерную конфигурацию (`replication-factor`). В дальнейшем значение `--init-replication-factor` игнорируется.
Этот параметр играет роль только в момент инициализации кластера. Bootstrap-лидер записывает это значение в конфигурацию кластера (`replication-factor`). В дальнейшем значение `--init-replication-factor` игнорируется.
Отредактировать фактор репликации, сохраненный в конфиге кластера, можно командой `picodata set-replication-factor`. Редактирование кластерного конфига сказывается только на новых добавляемых инстансах, но не затрагивает уже работающие.
Отредактировать фактор репликации, сохраненный в конфигурации кластера, можно командой `picodata set-replication-factor`. Редактирование конфигуарции сказывается только на вновь добавляемых инстансах, но не затрагивает уже работающие.
Этот параметр составляет часть конфигурации кластера и обозначает *желаемое* количество реплик в каждом репликасет.е
Этот параметр составляет часть конфигурации кластера и обозначает *желаемое* количество реплик в каждом репликасете.
При добавлении инстанса, фактор репликации будет записан в кластерную конфигурацию, но такой сценарий позволяет изменять аго только в сторону увеличения. Уменьшить фактор репликации можно командой `picodata set-replication-factor`, но опять же, с уже работающими инстансами ничего не произойдёт.
При добавлении инстанса фактор репликации будет записан в конфигурацию кластера, но такой сценарий позволяет изменять его только в сторону увеличения. При этом, сохраняется возможность уменьшить фактор репликации для вновь добавляемых инстансов командой `picodata set-replication-factor`(с уже работающими инстансами ничего не произойдет).
По мере усложнения топологии встаёт ещё один вопрос — как запретить пикодате объединять в репликасет инстансы из одного датацентра. Понятие датацентра здесь используется только как пример, на самом деле пикодата позволяет использовать любые удобные понятия — регион (`eu-east`), датацентр, стойка, сервер, или придумать свои обозначения (blue, green, yellow).
По мере усложнения топологии возникает еще один вопрос — как не допустить объединения в репликасет инстансов из одного и того же датацентра. Для этого введен параметр `--failure-domain` — _зона доступности_, отражающая признак физического размещения сервера, на котором выполняется инстанс Picodata. Это может быть как датацентр, так и какое-либо другое обозначение расположения: регион (например, `eu-east`), стойка, сервер, или собственное обозначение (blue, green, yellow). Ниже показан пример запуска инстанса Picodata с указанием зоны доступности:
```
picodata run --replication-factor 2 --failure-domain region=us,zone=us-west-1
......@@ -87,23 +88,23 @@ picodata run --replication-factor 2 --failure-domain region=us,zone=us-west-1
Добавление инстанса в репликасет происходит по следующим правилам:
- Если в каком-то репликасете количество инстансов меньше необходимого фактора репликации, новый инстанс добавляется в него при условии, что их фейл домены отличаются.
- Если подходящих репликасетов нет, пикодата создаёт новый репликасет.
- Если в каком-либо репликасете количество инстансов меньше необходимого фактора репликации, то новый инстанс добавляется в него при условии, что их параметры `--failure-domain` отличаются.
- Если подходящих репликасетов нет, то Picodata создаёт новый репликасет.
Параметр `--failure-domain` играет роль только в момент добавления инстанса в кластер. **Принадлежность инстанса репликасету впоследствии не меняется**.
Как и параметр `--advertise`, значение `failure-domain` каждого инстанса можно редактировать
Как и параметр `--advertise`, значение параметра`--failure-domain` каждого инстанса можно редактировать:
- Либо перезапустив инстанс с новыми параметрами.
- Либо в рантайме командой `picodata set-failure-domain`.
- Либо в процессе его работы командой `picodata set-failure-domain`.
Добавляемый инстанс должен обладать тем же набором ключей, которые уже есть в кластере. Например, инстанс `dc=msk` не сможет присоединиться к кластеру с `--failure-domain region=eu/us` и вернёт ошибку.
Добавляемый инстанс должен обладать тем же набором параметров, которые уже есть в кластере. Например, инстанс `dc=msk` не сможет присоединиться к кластеру с `--failure-domain region=eu/us` и вернёт ошибку.
## Группы репликасетов
Иногда бывает так, что в разных репликасетах хочется использовать разный фактор репликации или ограничить размер хранимых данных. Классический пример — разделение кластера на стораджа и роутеры.
Иногда бывает так, что в разных репликасетах хочется использовать разный фактор репликации или ограничить размер хранимых данных. Классический пример — разделение кластера на узлы хранения (`storage`) и узлы маршрутизации (`router`).
Это делается с помощью параметра `--replicaset-group`. По умолчанию инстансы добавляются в неявную группу `"default"`, но пользователь может насоздавать сколько угодно новых, перечислив их в параметре `--available-replicaset-groups`.
Такое разделение делается с помощью параметра `--replicaset-group`. По умолчанию инстансы добавляются в неявную группу `"default"`, но пользователь может создать сколько угодно новых групп, перечислив их в переменной `PICODATA_AVAILABLE_REPLICASET_GROUPS` подобным образом:
```bash
export PICODATA_AVAILABLE_REPLICASET_GROUPS=\
......@@ -111,7 +112,7 @@ export PICODATA_AVAILABLE_REPLICASET_GROUPS=\
"name=router:storage-weight=0"
```
Теперь при запуске инстансов можно будет указывать
Теперь при запуске инстансов можно будет указать группу:
```
picodata run --replicaset-group router
......@@ -121,26 +122,26 @@ picodata run --replicaset-group router
## Кейс: два датацентра по две реплики
Пикодата старается не объединять в один репликасет инстансы, у которых совпадает хотя бы один фейл домен. Но иногда это прямо таки необходимо. Чтобы ограничить пикодату в бесконечном создании репликасетов, можно воспользоваться флагом `--max-replicaset-count` (по умолчанию `inf`).
Picodata старается не объединять в один репликасет инстансы, у которых совпадает хотя бы один домен. Но иногда это прямо таки необходимо. Чтобы ограничить Picodata в бесконечном создании репликасетов, можно воспользоваться флагом `--max-replicaset-count` (по умолчанию `inf`).
Как и `--replication-factor`, параметр `--max-replicaset-count` можно назначать разным для разных групп репликасетов.
Как и другие параметры, `--max-replicaset-count` редактируется в любой момент:
- При добавлении нового инстанса
- В рантайме командой picodata set-max-replicaset-count
- В процессе его работы командой `picodata set-max-replicaset-count`
Единственное, `--max-replicaset-count` нельзя сделать меньше существующего количества репликасетов.
Важно учитывать, что параметр `--max-replicaset-count` нельзя сделать меньше существующего количества репликасетов.
## Файлы конфигурации
Пикодата позволяет передавать параметры из трёх мест (в порядке возрастания приоритета):
Существует три способа передать Picodata параметры конфигурации. Они приведены ниже в порядке возрастания приоритета:
1. Файл конфига (yaml / toml)
1. Файл конфигурации (yaml / toml)
2. Переменные окружения `PICODATA_<PARAM>=<VALUE>`
3. Аргументы командной строки `--param value`
Мы перечислили достаточно много разнобразных параметров, некоторые из которых достаточно развесистые. Пользуйтесь конфигами:
Мы перечислили достаточно много разнобразных параметров, некоторые из которых делают команду запуска достаточно длинной. Вместо отдельных команд можно использовать файл конифгурации. Пример:
<h5 a><strong><code>c1.toml</code></strong></h5>
......@@ -155,13 +156,13 @@ name = "router"
storage-weight = 0
```
## Ползучие воутеры (raft voter failover)
## Динамическое переключение голосующих узлов в Raft (Raft voter failover)
Все рафт ноды в кластере делятся на две роли - воутеры и лёрнеры. За консистентность отвечают только воутеры. Для коммита каждой транзакции требуется собрать кворум из `N/2 + 1` воутеров. Лернеры в кворуме не участвуют.
Все узлы Raft в кластере делятся на два типа: голосующие (`voter`) и неголосующие (`learner`). За консистентность Raft-группы отвечают только узлы первого типа. Для коммита каждой транзакции требуется собрать кворум из `N/2 + 1` из голосующих узлов. Неголосующие узлы в кворуме не участвуют.
Чтобы сохранить баланс между надёжностью кластера и беззаботностью его эксплуатации, пикодата обладает фишечкой — при смерти одного из воутеров (на которох держится кворум рафта и который терять очень не хочется) роль воутера автоматически передаётся одному из живых инстансов. Переключение происходит незаметно для пользователя.
Чтобы сохранить баланс между надёжностью кластера и удобством его эксплуатации, в Picodata предусмотрена удобная функция — динамическое переключение типа у узлов. Если один из голосующих узлов становится недоступен или прекращает работу (что может нарушить кворум в Raft), то тип `voter` автоматически присваивается одному из доступных неголосующих узлов. Переключение происходит незаметно для пользователя.
Количество воутеров в кластере не настраивается и зависит только от общего количества инстансов. Если инстансов 1 или 2, воутер один. Если инстансов 3 или 4, то воутера три. Для кластеров от 5 инстансов и больше - пять воутеров.
Количество голосующих узлов в кластере не настраивается и зависит только от общего количества инстансов. Если инстансов 1 или 2, то голосующий узел один. Если инстансов 3 или 4, то таких узлов три. Для кластеров с 5 или более инстансами — пять голосующих узлов.
## Configuration reference
......@@ -180,7 +181,7 @@ storage-weight = 0
: Socket bind address.
*env*: `PICODATA_LISTEN`
*default*: `localhost:3301`
`--peer <[host][:port]>`
: Address of other instance(s).
*env*: `PICODATA_PEER`
......@@ -190,7 +191,7 @@ storage-weight = 0
: Address the other instances should use to connect to this instance.
*env*: `PICODATA_ADVERTISE`
*default*: `%hostname%:%listen_port%`
:hammer_and_wrench:: Если `%listen% == "0.0.0.0"`, то надо подставлять `%hostname%`. Сейчас дефолт всегда просто `%listen%`.
:hammer_and_wrench:: Если `%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.
......@@ -201,7 +202,7 @@ storage-weight = 0
: Name of the instance.
*env*: `PICODATA_INSTANCE_ID`
*default*: `i%raft_id%`, e.g. `i1`, `i42`, etc.
:hammer_and_wrench:: Надо придумать, как идентифицировать клиентов в батче, если айдишник генерится только при обработке запроса. Ответ - по адвертайзу.
:hammer_and_wrench:: Надо придумать, как идентифицировать каждого клиента в больших наборах (advertise?). ID генерируется только при обработке запроса.
`--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.
......@@ -213,7 +214,7 @@ storage-weight = 0
: Name of the replicaset group. It's an error to run instance with a group changed.
*env*: `PICODATA_REPLICASET_GROUP`
*default*: `default`
:hammer_and_wrench: Зачем это? Без картинки, поясняющей архитектуру кластера, объяснить сложновато .
:hammer_and_wrench: Зачем это? Без картинки, поясняющей архитектуру кластера, объяснить сложновато.
`--init-replication-factor <number>`
: Total number of replicas (copies of data) for each replicaset in the current group.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment