diff --git a/docs/clustering.md b/docs/clustering.md index 3d2911524abc53655354da4c5903c84de6ef4e2a..0e9a547feb6dbb4809d98f3fc4be6ef2bfa7ed6c 100644 --- a/docs/clustering.md +++ b/docs/clustering.md @@ -62,7 +62,7 @@ picodata run --instance-id iN --listen iN --peer i1 # Обработка запроÑов -### extern "C" fn join() +### \#\[proc\] fn raft_join() Ð—Ð½Ð°Ñ‡Ð¸Ñ‚ÐµÐ»ÑŒÐ½Ð°Ñ Ñ‡Ð°ÑÑ‚ÑŒ вÑей логики по управлению топологией находитÑÑ Ð² хранимой процедуре `raft_join`. Ðргументом Ð´Ð»Ñ Ð½ÐµÐµ ÑвлÑетÑÑ ÑÐ»ÐµÐ´ÑƒÑŽÑ‰Ð°Ñ Ñтруктура: @@ -120,3 +120,24 @@ struct Peer { - Генерировать значение `raft_id` может только лидер Raft-группы. Ожидание `ConfChangeV2` лидерÑтва не требует. - Помимо вÑевозможных идентификаторов, ответ Ñодержит ÑпиÑок голоÑующих членов Raft-группы. Они понадобÑÑ‚ÑÑ Ð½Ð¾Ð²Ð¾Ð¼Ñƒ инÑтанÑу чтобы знать адреÑа ÑоÑедей и нормально Ñ Ð½Ð¸Ð¼Ð¸ общатьÑÑ. - Также ответ Ñодержит параметр `box_replication`, который требуетÑÑ Ð´Ð»Ñ Ð¿Ñ€Ð°Ð²Ð¸Ð»ÑŒÐ½Ð¾Ð¹ наÑтройки репликации. + +# Логика conf_change_loop + +Ð’Ñе узлы Raft в клаÑтере делÑÑ‚ÑÑ Ð½Ð° два типа: голоÑующие (`voter`) и неголоÑующие (`learner`). Ðа каждом инÑтанÑе клаÑтера приÑутÑтвует поток, управлÑющий конфигурацией Raft-группы (ÑоÑтавом `voters` / `learners`). Реальные Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ñ‚ÐµÐ¼ не менее может генерировать только лидер, на оÑтальных инÑтанÑах Ñтот поток Ñпит и ничего не делает. + +Поток предÑтавлÑет Ñобой беÑконечный цикл. Ðа каждой итерации выполнÑетÑÑ Ð¿Ñ€Ð¾Ð²ÐµÑ€ÐºÐ°, что ÑоÑтав `voters` / `learners` ÑоответÑтвует ÑоÑтоÑнию инÑтанÑов, и при необходимоÑти Ñти Ð¸Ð·Ð¼ÐµÐ½ÐµÐ½Ð¸Ñ Ð¿Ð°Ñ‡ÐºÐ¾Ð¹ запиÑываютÑÑ Ð² Raft-журнал: + +- ИнÑтанÑÑ‹ в ÑтатуÑе `health: Loading` довавлÑÑŽÑ‚ÑÑ ÐºÐ°Ðº неголоÑующие. +- ЕÑли еÑÑ‚ÑŒ возможноÑÑ‚ÑŒ, `Offline` инÑтанÑÑ‹ передают право голоÑа другим `Online`. +- ЕÑли общее количеÑтво голоÑующих инÑтанÑов оказываетÑÑ Ð¼ÐµÐ½ÑŒÑˆÐµ целевого, `Online` инÑтанÑÑ‹ получают право голоÑа. + +КоличеÑтво голоÑующих узлов в клаÑтере не наÑтраиваетÑÑ Ð¸ завиÑит только от общего количеÑтва инÑтанÑов. ЕÑли инÑтанÑов 1 или 2, то голоÑующий узел один. ЕÑли инÑтанÑов 3 или 4, то таких узлов три. Ð”Ð»Ñ ÐºÐ»Ð°Ñтера Ñ 5 или более инÑтанÑами — пÑÑ‚ÑŒ голоÑующих узлов. + +# Graceful shutdown + +Чтобы выключение прошло штатно и не имело негативных поÑледÑтвий необходимо Ñледующее: + +- ИнÑÑ‚Ð°Ð½Ñ Ð½Ðµ должен оÑтаватьÑÑ Ð²Ð¾ÑƒÑ‚ÐµÑ€Ð¾Ð¼, пока еÑÑ‚ÑŒ другие онлайн кандидаты. +- ИнÑÑ‚Ð°Ð½Ñ Ð½Ðµ должен оÑтаватьÑÑ Ð»Ð¸Ð´ÐµÑ€Ð¾Ð¼. + +Чтобы Ñтого добитьÑÑ, каждый инÑÑ‚Ð°Ð½Ñ Ð½Ð° `on_shutdown` триггер отправлÑет лидеру Ð·Ð°Ð¿Ñ€Ð¾Ñ `UpdatePeerRequest{ health: Offline }`. ÐепоÑредÑтвенно изменением роли `voter` -> `learner` занимаетÑÑ Ð¾Ñ‚Ð´ÐµÑŒÐ½Ñ‹Ð¹ поток на лидере (тот Ñамый `conf_change_loop`), инÑÑ‚Ð°Ð½Ñ Ñ‚Ð¾Ð»ÑŒÐºÐ¾ дожидаетÑÑ ÐµÐ³Ð¾ применениÑ. diff --git a/src/traft/node.rs b/src/traft/node.rs index acac14e88d63793e246040feab0ce732c9ac3d28..ce99135ec8ff786c2593a0af9b61edc7c9146e6f 100644 --- a/src/traft/node.rs +++ b/src/traft/node.rs @@ -317,6 +317,8 @@ impl Node { .recv::<Peer>() } + /// Only the conf_change_loop on a leader is eligible to call this function. + /// /// **This function yields** fn propose_conf_change( &self,