diff --git a/docs/topology.md b/docs/topology.md new file mode 100644 index 0000000000000000000000000000000000000000..54cba893d94829711452fd75f4d6e5c64408c255 --- /dev/null +++ b/docs/topology.md @@ -0,0 +1,234 @@ +--- +title: Topology RFC (v3.1) +tags: Picodata, RFC +--- + +## Topology RFC (v3.1) + +*2022-06-13* +*Yaroslav Dynnikov* + +Мы раÑÑмотрим неÑколько Ñценариев работы Ñ ÐºÐ»Ð°Ñтером. Ð’Ñе они оÑнованы на одном и том же принципе, а ÑложноÑÑ‚ÑŒ Ð´ÐµÐ¿Ð»Ð¾Ñ Ñ„Ð°ÐºÑ‚Ð¸Ñ‡ÐµÑки завиÑит только от ÑложноÑти Ñамой топологии. + +[TOC] + +--- + +## КлаÑтер Ñ Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ð¼Ð¸ уÑилиÑми + +С минимальными, так Ñ Ð¼Ð¸Ð½Ð¸Ð¼Ð°Ð»ÑŒÐ½Ñ‹Ð¼Ð¸. ОбÑзательных параметров у пикодаты нет ÑовÑем. Так что одноинÑтанÑовый клаÑтер запуÑкаетÑÑ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð¾Ð¹ + +``` +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`: +```shell +picodata run --listen 0.0.0.0 --advertise 192.168.0.1 +``` + +Ðа `192.168.0.2`: +```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` не хранитÑÑ Ð² клаÑтерной конфигурации. ПоменÑÑ‚ÑŒ его можно на реÑтарте. + +Во-вторых, надо дать инÑтанÑам возможноÑÑ‚ÑŒ обнаружить друг друга. Ð’ параметре `--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`. + +```bash +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` + +Мы перечиÑлили доÑтаточно много разнобразных параметров, некоторые из которых доÑтаточно развеÑиÑтые. ПользуйтеÑÑŒ конфигами: + +<h5 a><strong><code>c1.toml</code></strong></h5> + +``` +[[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%` +: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. +*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. +:hammer_and_wrench:: Ðадо придумать, как идентифицировать клиентов в батче, еÑли айдишник генеритÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ при обработке запроÑа. Ответ - по адвертайзу. + +`--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* +:hammer_and_wrench:: ОбъÑÑнить правила "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` +:hammer_and_wrench: Зачем Ñто? Без картинки, поÑÑнÑющей архитектуру клаÑтера, объÑÑнить Ñложновато . + +`--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` +:hammer_and_wrench: УчитываетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ при Ñоздании группы. Потом игнорируетÑÑ. + +`--init-storage-weight <number>` +: Proportional capacity of current instance. Common for each instance in the current group. +*env*: `PICODATA_INIT_STORAGE_WEIGHT` +*default*: `1` +:hammer_and_wrench: УчитываетÑÑ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ при Ñоздании группы. Потом игнорируетÑÑ. + +`--max-replicaset-count` +: Maximum number of replicasets in the current group. +*env*: `PICODATA_MAX_REPLICASET_COUNT` +*default*: don't modify +:hammer_and_wrench: ЕÑли меньше текущего размера группы, то игнорируетÑÑ. ЕÑли в текущей группе нет меÑта, то ошибка. ЕÑли больше — наÑтройка применÑетÑÑ Ðº текущей группе репликаÑетов. \ No newline at end of file