diff --git a/docs/clustering.md b/docs/clustering.md index 289a9e0c75c8d408ce2b9c8af305db16d1b03509..c618ec265b39e8941494f1f3f954ebdf274d4533 100644 --- a/docs/clustering.md +++ b/docs/clustering.md @@ -31,7 +31,7 @@ picodata run --instance-id iN --listen iN --peer i1,i2 ### fn start_discover() Дочерний процеÑÑ Ð½Ð°Ñ‡Ð¸Ð½Ð°ÐµÑ‚ Ñвоё ÑущеÑтвование Ñ Ð²Ñ‹Ð·Ð¾Ð²Ð° `box.cfg()` и вызова функции `start_discover`. -ЕÑли вдруг из ÑпейÑов обнаруживаетÑÑ, что нода уже была забутÑтрапленна, то никакой алгоритм диÑкавери делаь и не надо, и инÑÑ‚Ð°Ð½Ñ Ñразу переходит на Ñтап `postjoin()`. Ð’ противном Ñлучае, еÑли Ñто первый запуÑк, из алгоритма диÑкавери мы получаем флаг `its_me` и Ð°Ð´Ñ€ÐµÑ Ð»Ð¸Ð´ÐµÑ€Ð°. Сам лидер выполнÑет `start_boot`, поÑле чего выполнÑет `postjoin()`. ОÑтальные инÑтанÑÑ‹ (не только проигравшие пиры, но и вÑе будущие) ребутÑтрапÑÑ‚ÑÑ Ð¸ идут делать `start_join`. +ЕÑли вдруг из ÑпейÑов обнаруживаетÑÑ, что нода уже была забутÑтрапленна, то никакой алгоритм диÑкавери делаь и не надо, и инÑÑ‚Ð°Ð½Ñ Ñразу переходит на Ñтап `postjoin()`. Ð’ противном Ñлучае, еÑли Ñто первый запуÑк, из алгоритма диÑкавери мы получаем флаг `its_me` и Ð°Ð´Ñ€ÐµÑ Ð»Ð¸Ð´ÐµÑ€Ð°. Сам лидер (единÑтвенный `its_me == true`) выполнÑет `start_boot`, поÑле чего выполнÑет `postjoin()`. ОÑтальные инÑтанÑÑ‹ (не только проигравшие пиры, но и вÑе будущие) ребутÑтрапÑÑ‚ÑÑ Ð¸ идут делать `start_join`. ### fn start_boot() @@ -44,7 +44,9 @@ picodata run --instance-id iN --listen iN --peer i1,i2 Вызову `start_join` вÑегда предшеÑтвует ребутÑтрап (удаление БД и реÑтарт процеÑÑа), поÑтому ни бокÑа, ни ÑпейÑов на Ñтом Ñтапе Ñнова нет. Сама Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð´Ð¾Ñтаточно примитивнаÑ. -ИнÑÑ‚Ð°Ð½Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð»Ñет Ð·Ð°Ð¿Ñ€Ð¾Ñ `join` на лидера (лидер извеÑтен поÑле диÑкавери). Лидер шушукаетÑÑ Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð¾Ð¹, и еÑли вÑÑ‘ хорошо, в ответ приÑылает необходимую Ð´Ð»Ñ `box.cfg()` информацию - `raft_id`, `raft_group`, `insance_uuid`, `replicaset__uuid`, `replication`, `read_only`. +ИнÑÑ‚Ð°Ð½Ñ Ð¾Ñ‚Ð¿Ñ€Ð°Ð²Ð»Ñет Ð·Ð°Ð¿Ñ€Ð¾Ñ `join` на лидера (лидер извеÑтен поÑле диÑкавери). Лидер шушукаетÑÑ Ñ Ð³Ñ€ÑƒÐ¿Ð¿Ð¾Ð¹, и еÑли вÑÑ‘ хорошо, в ответ приÑылает необходимую информацию: +- `raft_id` и `raft_group` - Ð´Ð»Ñ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ð¸ рафт ноды; +- `insance_uuid`, `replicaset_uuid`, `replication`, `read_only` - Ð´Ð»Ñ `box.cfg`. Получив вÑе наÑтройки, инÑÑ‚Ð°Ð½Ñ Ð·Ð°Ñовывает их в `box.cfg()`, и поÑле Ñтого перÑиÑтит `raft_group` Ñ Ð°ÐºÑ‚ÑƒÐ°Ð»ÑŒÐ½Ñ‹Ð¼Ð¸ адреÑами других инÑтанÑов. Без Ñтого инÑÑ‚Ð°Ð½Ñ Ð½Ðµ Ñможет отвечать на рафт ÑообщениÑ. Рчтобы запиÑи в `raft_group` не были потёрты менее актуальными из рафт лога, ÐºÐ°Ð¶Ð´Ð°Ñ Ð¼Ð°Ñ€ÐºÐ¸Ñ€ÑƒÐµÑ‚ÑÑ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð¸ÐµÐ¼ `commit_index`. @@ -52,7 +54,7 @@ picodata run --instance-id iN --listen iN --peer i1,i2 ### fn postjoin() -Логика `postjoin()` Ð´Ð»Ñ Ð²Ñех инÑтанÑов одинакова. К Ñтому моменту на инÑтанÑе уже инициализированы правильные ÑпейÑÑ‹ и возможно даже ÑущеÑтвует предыÑÑ‚Ð¾Ñ€Ð¸Ñ Ñ€Ð°Ñ„Ñ‚ журнала. ИнÑÑ‚Ð°Ð½Ñ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð¸Ñ€ÑƒÐµÑ‚ рафт ноду и получает read barrier. ЕÑли вÑÑ‘ хорошо, то в актуальноÑти рафт лога ÑомневатьÑÑ Ð½Ðµ прихоитÑÑ. Из рафт лога ÑтановÑÑ‚ÑÑ Ð¸Ð·Ð²ÐµÑтны параметры репликации, и инÑÑ‚Ð°Ð½Ñ ÑинхронизируемÑÑ Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ð¼Ð¸. +Логика `postjoin()` Ð´Ð»Ñ Ð²Ñех инÑтанÑов одинакова. К Ñтому моменту на инÑтанÑе уже инициализированы правильные ÑпейÑÑ‹ и возможно даже ÑущеÑтвует предыÑÑ‚Ð¾Ñ€Ð¸Ñ Ñ€Ð°Ñ„Ñ‚ журнала. ИнÑÑ‚Ð°Ð½Ñ Ð¸Ð½Ð¸Ñ†Ð¸Ð°Ð»Ð¸Ð·Ð¸Ñ€ÑƒÐµÑ‚ рафт ноду и получает read barrier (Ñто позволÑет убедитьÑÑ, что рафт лог актуален). Из рафт лога ÑтановÑÑ‚ÑÑ Ð¸Ð·Ð²ÐµÑтны параметры репликации, и инÑÑ‚Ð°Ð½Ñ ÑинхронизируетÑÑ Ñ Ñ€ÐµÐ¿Ð»Ð¸ÐºÐ°Ð¼Ð¸. ОÑтаётÑÑ Ð¾Ð´Ð¸Ð½ маленький штришок - проверить Ñвой ÑÑ‚Ð°Ñ‚ÑƒÑ voter / learner, при необходимоÑти кинуть Ð·Ð°Ð¿Ñ€Ð¾Ñ Ð½Ð° промоут до воутера (вÑÑ‘ тот же `join`, лидер извеÑтен поÑле Ð¿Ð¾Ð»ÑƒÑ‡ÐµÐ½Ð¸Ñ read barrier), и дождатьÑÑ ÐµÐ³Ð¾ применениÑ.