From c63ef1c6e32226438b3398fec50bfba288fabb4a Mon Sep 17 00:00:00 2001
From: "a.tolstoy" <a.tolstoy@picodata.io>
Date: Wed, 1 Nov 2023 16:53:06 +0300
Subject: [PATCH] clustering.md: fix lists, links, formatting

---
 docs/architecture/clustering.md | 104 ++++++++++++++++----------------
 1 file changed, 51 insertions(+), 53 deletions(-)

diff --git a/docs/architecture/clustering.md b/docs/architecture/clustering.md
index 1786d6f9..c8554388 100644
--- a/docs/architecture/clustering.md
+++ b/docs/architecture/clustering.md
@@ -25,12 +25,12 @@ picodata run --instance-id iN --listen iN --peer i1
 [документе](discovery.md).
 В контексте сборки кластера важно лишь понимать, что этот алгоритм
 позволяет не более чем одному инстансу (peer'у) создать raft-группу,
-т.е. стать инстансом с raft_id=1. Если таких инстансов будет несколько,
+т.е. стать инстансом с `raft_id=1`. Если таких инстансов будет несколько,
 то и raft-групп, а следовательно и кластеров Picodata получится
 несколько.
 
-Топологией raft-группы управляет алгоритм Raft, реализованный в виде
-крейта `raft-rs`.
+Топологией raft-группы управляет алгоритм Raft, реализованный в виде крейта
+[raft-rs](https://doc.rust-lang.org/rust-by-example/crates.html){:target="_blank"}.
 
 ## Этапы инициализации кластера {: #cluster-bootstrap-stages }
 На схеме ниже показаны этапы жизненного цикла инстанса в контексте его
@@ -64,11 +64,11 @@ picodata run --instance-id iN --listen iN --peer i1
 Выполнение дочернего процесса начинается с вызова функции
 [`start_discover()`](#fn-start_discover) и далее следует алгоритму. При
 необходимости дочерний процесс может попросить родителя удалить все
-файлы БД (см. раздел ["Ребутстрап"](#Ребутстрап)). Это используется для
+файлы БД (см. раздел [Ребутстрап](#rebootstrap)). Это используется для
 повторной инициализации инстанса с нормальным `replicaset_uuid` вместо
 рандомного.
 
-### Ребутстрап {: #revootsrap }
+### Ребутстрап {: #rebootstrap }
 
 В СУБД Tarantool имеются две особенности, из-за которых процесс инициализации
 выглядит следующим образом:
@@ -79,11 +79,11 @@ picodata run --instance-id iN --listen iN --peer i1
 2. Инициализация сервера iproto, реализующего бинарный сетевой протокол
    Tarantool, выполняется той же функцией `box.cfg()`.
 
-В совокупности эти две особенности создают проблему курицы и яйца:
+В совокупности эти две особенности создают проблему "курицы и яйца":
 
-- Инстанс не может общаться по сети, пока не узнает принадлежность
-  репликасету.
-- Принадлежность репликасету невозможно узнать без общения по сети.
+- инстанс не может общаться по сети, пока не узнает принадлежность
+  репликасету;
+- принадлежность репликасету невозможно узнать без общения по сети.
 
 Чтобы эту проблему решить, Picodata инициализируется со случайно
 сгенерированными идентификаторами, а позже перезапускает процесс,
@@ -100,7 +100,7 @@ discovery не будет, инстанс сразу перейдет к эта
 противном случае, если место инстанса в кластере еще не известно,
 алгоритм discovery определяет значение флага `i_am_bootstrap_leader` и
 адрес лидера raft-группы. Далее инстанс сбрасывает свое состояние (см.
-["Ребутстрап"](#Ребутстрап)), чтобы повторно провести инициализацию
+[Ребутстрап](#rebootstrap)), чтобы повторно провести инициализацию
 `box.cfg()`, теперь уже с известными параметрами. Сам лидер
 (единственный с `i_am_bootstrap_leader == true`) выполняет функцию
 `start_boot()`. Остальные инстансы переходят к функции `start_join()`.
@@ -119,7 +119,7 @@ discovery не будет, инстанс сразу перейдет к эта
 ### fn start_join()
 
 Вызову функции `start_join()` всегда предшествует
-[ребутстрап](#Ребутстрап) (удаление всех данных и перезапуск процесса),
+[ребутстрап](#rebootstrap) (удаление всех данных и перезапуск процесса),
 поэтому на данном этапе в БД нет ни модуля `box`, ни пространства
 хранения. Функция `start_join()` имеет простое устройство:
 
@@ -128,7 +128,8 @@ discovery не будет, инстанс сразу перейдет к эта
 для инициализации информацию:
 
 Для инициализации raft-узла:
-- идентификатор `raft_id`,
+
+- идентификатор `raft_id`;
 - данные таблицы `_picodata_peer_address`.
 
 Для первичного вызова `box.cfg()`:
@@ -152,24 +153,20 @@ raft-группы.
 
 Функция `postjoin()` выполняет следующие действия:
 
-- Инициализирует HTTP-сервер в соответствии с параметром `--http-listen`.
-
-- Запускает Lua-скрипт, указанный в аргументе `--script`.
-
-- Инициализирует узел Raft, который начинает взаимодействовать с
-  raft-группой.
-
-- В случае, если других кандидатов нет, инстанс тут же
-  избирает себя лидером группы.
-
-- Устанавливает триггер `on_shutdown`, который обеспечит
-  [корректное завершение работы инстанса](#Graceful-shutdown).
+- инициализирует HTTP-сервер в соответствии с параметром `--http-listen`.
+- запускает Lua-скрипт, указанный в аргументе `--script`;
+- инициализирует узел Raft, который начинает взаимодействовать с
+  raft-группой;
+- в случае, если других кандидатов нет, инстанс тут же
+  избирает себя лидером группы;
+- устанавливает триггер `on_shutdown`, который обеспечит
+  [корректное завершение работы инстанса](#graceful-shutdown).
 
 Последним шагом инстанс оповещает кластер о том, что он готов проходить
 настройку необходимых подсистем (репликации, шардинга, и т.д.). Для
 этого лидеру отправляется запрос на обновление `target_grade` текущего
 инстанса до уровня `Online`, после чего за дальнейшие действия будет
-отвечать специальный поток управления [topology governor](#Topology-governor).
+отвечать специальный поток управления [topology governor](#topology-governor).
 
 Как только запись с обновленным грейдом будет зафиксирована в Raft, узел
 готов к использованию.
@@ -180,12 +177,12 @@ raft-группы.
 инстанса во всех трех вышеописанных сценариях — `start_discover`,
 `start_boot`, `start_join`.
 
-Инициализация инстанса сводится к следующим шагам:
+Инициализация инстанса подразумевает следующие шаги:
 
-- создание `data_dir`,
-- первичный вызов `box.cfg`,
-- инициализация `package.preload.vshard`,
-- инициализация хранимых процедур (`box.schema.func.create`),
+- создание `data_dir`;
+- первичный вызов `box.cfg`;
+- инициализация `package.preload.vshard`;
+- инициализация хранимых процедур (`box.schema.func.create`);
 - создание системных таблиц (`_picodata_raft_log` и т.д).
 
 Параметры первичного вызова `box.cfg` зависят от конкретного сценария:
@@ -252,17 +249,17 @@ struct Instance {
 Цель такого запроса сводится к добавлению нового инстанса в raft-группу.
 Для этого алгоритма справедливы следующие тезисы:
 
-- Запрос `rpc::join` всегда делает инстанс без снапшотов.
-- В процессе обработки запроса в raft-журнал добавляется запись
+- запрос `rpc::join` всегда делает инстанс без снапшотов;
+- в процессе обработки запроса в raft-журнал добавляется запись
   `op::PersistPeer { peer }`, при этом `current_grade: Offline`,
   `target_grade: Offline` (подробнее о них в разделе [topology
-  governor](#Topology-governor)).
-- В ответ выдается всегда новый `raft_id`, никому другому ранее не
-  принадлежавший.
-- Помимо идентификаторов нового инстанса, ответ содержит список
+  governor](#topology-governor));
+- в ответ выдается всегда новый `raft_id`, никому другому ранее не
+  принадлежавший;
+- помимо идентификаторов нового инстанса, ответ содержит список
   голосующих членов raft-группы. Они необходимы новому инстансу для
-  того чтобы отвечать на запросы от raft-лидера.
-- Также ответ содержит параметр `box_replication`, который требуется для
+  того чтобы отвечать на запросы от raft-лидера;
+- также ответ содержит параметр `box_replication`, который требуется для
   правильной настройки репликации.
 
 ## Graceful shutdown
@@ -270,9 +267,9 @@ struct Instance {
 Чтобы выключение прошло штатно и не имело негативных последствий,
 необходимо следить за соблюдением следующих условий:
 
-- Инстанс не должен оставаться голосующим, пока есть другие кандидаты в
-  состоянии `Online`.
-- Инстанс не должен оставаться лидером.
+- инстанс не должен оставаться голосующим, пока есть другие кандидаты в
+  состоянии `Online`;
+- инстанс не должен оставаться лидером.
 
 Чтобы этого добиться, каждый инстанс при срабатывании триггера
 `on_shutdown` отправляет лидеру запрос `UpdatePeerRequest {
@@ -316,7 +313,6 @@ Cartridge) Picodata не использует понятие "состояния
 какой-то период времени, после чего их необходимо снова привести в
 актуальное состояние.
 
-
 На основе совокупности грейдов и их инкарнаций `governor_loop` на каждой
 итерации бесконечного цикла генерирует активности (activity) и пытается
 их организовать. Пока не организует, никаких других изменений в текущих
@@ -324,12 +320,13 @@ Cartridge) Picodata не использует понятие "состояния
 завершатся ошибкой, то на следующей итерации они будут перевычислены с
 учетом новых целей.
 
-Инкарнации грейдов вычисляются по следующему принципу.
-- Каждый раз когда `target_grade` инстанса получает значение `Online`,
-    его инкарнация увеличивается на 1.
-- Все остальные изменения грейдов копируют инкарнацию с противоположного
-    грейда, то есть при изменении `target_grade` инкарнация копируется с
-    `current_grade`, при изменении `current_grade` — с `target_grade`.
+Инкарнации грейдов вычисляются по следующему принципу:
+
+- каждый раз когда `target_grade` инстанса получает значение `Online`,
+  его инкарнация увеличивается на 1;
+- все остальные изменения грейдов копируют инкарнацию с противоположного
+  грейда, то есть при изменении `target_grade` инкарнация копируется с
+  `current_grade`, при изменении `current_grade` — с `target_grade`.
 
 Дальше перечислены активности, которыми занимается `governor_loop`, в
 том же порядке, в котором он к ним приступает.
@@ -347,13 +344,14 @@ Cartridge) Picodata не использует понятие "состояния
 
 Правила выбора новой конфигурации описаны в
 `picodata::governor::cc::raft_conf_change` и заключаются в следующем:
-- Любые инстансы, переходящие в грейд `Expelled`, удаляются из
+
+- любые инстансы, переходящие в грейд `Expelled`, удаляются из
   raft-группы;
-- Голосующие инстансы, переходящие в грейд `Offline`, перестают быть
+- голосующие инстансы, переходящие в грейд `Offline`, перестают быть
   голосующими (становятся `learners`) и для них находится замена;
-- Среди свежедобавленных инстансов с текущим грейдом `Online`
-    подбирается необходимое количество голосующих инстансов (`voters`),
-    остальные добавляются как `learners`;
+- среди свежедобавленных инстансов с текущим грейдом `Online`
+  подбирается необходимое количество голосующих инстансов (`voters`),
+  остальные добавляются как `learners`.
 
 <!-- [TODO](#Предстоит сделать) Новые воутеры должны выбираться с учетом failure
 domain'ов. -->
-- 
GitLab