Кворум в кластере простыми словами: зачем нужен третий узел
Вы читаете документацию к очередной кластерной системе — Proxmox, Kubernetes, etcd, Docker Swarm, да хоть Redis Sentinel — и везде натыкаетесь на одну и ту же фразу: «минимум 3 узла для отказоустойчивости», «нечётное число нод», «кворум не набран». Двух узлов вроде бы достаточно — один упал, второй работает, чего ещё надо? Но именно на этой логике почти все и спотыкаются: два узла не дают отказоустойчивости, они дают лишь второй экземпляр той же проблемы. Разберёмся, что такое кворум на самом деле, откуда берётся требование к нечётности и почему три — это не круглое число «для надёжности», а нижняя математическая граница, ниже которой сам механизм просто не работает.
Содержание
- Что такое кворум и почему «хоть кто-то живой» не работает
- Split-brain: что происходит без кворума при разрыве сети
- Математика нечётных чисел: почему четвёртый узел не помогает
- Как кворум реализован на практике в разных системах
- Witness-узел: как получить третий голос без третьего полноценного сервера
- Практические рекомендации: когда 2 узла допустимы, а когда нужны честные 3
Что такое кворум и почему «хоть кто-то живой» не работает
Кворум — это минимальное число участников группы, которое должно согласиться с решением, чтобы оно считалось принятым. Слово взято из парламентской практики: совет директоров не может провести голосование, если в зале нет кворума — даже если пришедшие единогласно проголосовали «за». Правило звучит не «решение принимает тот, кто есть», а «решение принимает тот, кого больше половины от списочного состава».
Разница критична. Представьте совет из 5 директоров, трое из которых заболели и не смогли приехать. Оставшиеся двое — это не большинство, значит, их решения не имеют силы, даже если они единогласны. Это защита от ситуации, когда меньшинство от имени всей организации принимает решения, которые могут быть отменены, когда на связь выйдут отсутствующие.
В распределённой системе роль «директоров» играют узлы кластера, а «голосование» происходит постоянно и незаметно: кто сейчас мастер, какая нода держит блокировку, какую реплику считать актуальной, можно ли безопасно стартовать виртуалку на этом узле. Кворум здесь решает ту же задачу, что и в совете директоров: не дать меньшинству узлов принимать решения, которые могут разойтись с решениями другой части системы.
Ключевая техническая деталь: кворум считается не от количества узлов, которые могут ответить прямо сейчас, а от общего списочного состава кластера — конфигурации, зафиксированной при его создании. Если в кластере 5 узлов, кворум — это 3, независимо от того, сколько узлов сейчас доступно. Именно эта фиксация состава и делает механизм надёжным: она не даёт постфактум пересчитать, кто «главнее».
Split-brain: что происходит без кворума при разрыве сети
Самый частый сценарий, ради которого вообще придуман кворум, — не падение узла, а разрыв связи между частями кластера (network partition). Разница принципиальна: упавший узел просто перестаёт существовать для остальных, а при разрыве сети обе половины кластера живы, работают и физически способны продолжать выполнять операции — они просто перестают видеть друг друга.
Представьте кластер виртуализации из двух узлов, между которыми оборвался канал связи (переключился свитч, отвалился линк, кто-то не туда воткнул патч-корд). Оба физических сервера продолжают исправно работать. Обе половины кластера видят: «сосед не отвечает». Без внешнего механизма, который скажет каждой половине, кто из них сейчас «главный», у системы есть два одинаково правдоподобных, но взаимоисключающих варианта поведения:
- Каждая половина решает, что она осталась одна, и продолжает работать как единственный источник истины.
- Каждая половина решает не рисковать и останавливает все операции.
Первый вариант называется split-brain («расщеплённый мозг») и на практике — самый разрушительный сценарий в кластерных системах. Конкретный пример: в кластере виртуализации HA-менеджер каждого узла следит за тем, что виртуалка vm-101 должна быть запущена. Если связь оборвалась и обе половины решили, что они «главные», обе могут независимо запустить vm-101 — на двух разных физических серверах одновременно, с одним и тем же диском на shared-хранилище. Итог — повреждение данных, потому что два инстанса гостевой ОС пишут в один и тот же блочный образ без всякой координации между собой. Для СУБД тот же сценарий выглядит как два «мастера», одновременно принимающих запись, чьи данные после восстановления связи придётся сливать вручную.
Кворум решает эту проблему жёстко и без вариантов: он гарантирует, что продолжать принимать решения может только та часть кластера, где строгое большинство узлов от списочного состава. Другая часть, оставшаяся в меньшинстве, автоматически переходит в защитный режим — блокирует запись, останавливает сервисы с HA, отказывается запускать виртуалки — и ждёт восстановления связи. Не потому что она «сломана», а потому что у неё физически нет способа доказать, что она не изолированное меньшинство.
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверМатематика нечётных чисел: почему четвёртый узел не помогает
Вот здесь начинается самая контринтуитивная часть. Формула кворума простая: для кластера из N узлов кворум — это floor(N/2) + 1, то есть «половина плюс один», округлённая вниз. Дальше начинается арифметика, которая объясняет, почему в кластерных системах почти никогда не встретишь рекомендацию «4 узла».
| Всего узлов (N) | Нужно для кворума | Сколько узлов может отказать | Чётность |
|---|---|---|---|
| 2 | 2 | 0 | чётное |
| 3 | 2 | 1 | нечётное |
| 4 | 3 | 1 | чётное |
| 5 | 3 | 2 | нечётное |
| 6 | 4 | 2 | чётное |
| 7 | 4 | 3 | нечётное |
Посмотрите на строки 3 и 4: кластер из 3 узлов переживает отказ одного, и кластер из 4 узлов тоже переживает отказ только одного. Четвёртый узел не добавил устойчивости к отказам — он добавил стоимость (ещё один сервер, ещё одна лицензия, ещё один канал связи), но допустимое число отказов осталось тем же самым. Хуже того: при разрыве связи ровно пополам — 2 и 2 — у кластера из 4 узлов не находится большинства ни в одной из половин, и весь кластер уходит в отказ, хотя формально «живы» все четыре узла. У кластера из 3 узлов при любом мыслимом разрыве связи одна из сторон получает 2 узла против 1 — большинство определяется однозначно, третьей стороны для голосования не остаётся никогда.
Это и есть причина, по которой нечётные числа узлов эффективнее чётных: при разрыве связи чётное число узлов может разделиться на две равные половины без явного большинства ни у одной стороны, а нечётное — не может в принципе, потому что нечётное число нельзя разделить на две равные целые части. Ровно поэтому в документации etcd, Consul, ZooKeeper, corosync (на котором работает Proxmox), Galera Cluster и десятков других систем встречается один и тот же совет: 3, 5, 7 узлов, никогда не 2, 4, 6.
Отсюда прямой практический вывод: минимальный имеющий смысл размер отказоустойчивого кластера — 3 узла, и это не круглое число из маркетинговой брошюры, а нижняя граница, на которой механизм кворума впервые начинает давать реальную защиту от split-brain. Кластер из 2 узлов эту защиту дать не может ни при какой конфигурации — при разрыве связи между ними кворум (2 из 2) не набирается ни в одной из половин, и либо обе останавливаются, либо (в конфигурациях без честного кворума) обе продолжают работать, воссоздавая ровно ту катастрофу, которую кворум должен предотвращать.
Как кворум реализован на практике в разных системах
Абстрактная математика одна и та же, но конкретный механизм подсчёта голосов у каждой системы свой — полезно понимать хотя бы в общих чертах, потому что от этого зависит, что именно вы увидите в логах при разрыве связи.
Corosync + votequorum (на нём построен кластер Proxmox VE). Каждый узел по умолчанию имеет один голос, суммарное число голосов сравнивается с порогом кворума. Посмотреть текущее состояние:
pvecm status
В выводе интересна строка Quorate: Yes/No — набран ли кворум прямо сейчас — и Expected votes — сколько голосов ожидается при полном составе кластера.
Raft-консенсус (etcd, Consul, CockroachDB, управляющий слой Kubernetes/k3s). Здесь кворум нужен не только для «жив кластер или нет», но и для выбора лидера и подтверждения каждой записи в журнал — запись считается зафиксированной только после того, как её подтвердило большинство узлов. Проверить состояние etcd-кластера:
etcdctl endpoint status --cluster -w table
Подробный разбор частых ошибок именно с etcd-кворумом на k3s — с конкретными сообщениями об ошибках и их причинами — есть в статье «k3s на сервере: частые ошибки и решения».
Docker Swarm. Менеджеры кластера тоже держат Raft-консенсус между собой (это отдельная роль от рабочих нод-воркеров, которых может быть сколько угодно и чётность для них не важна). Число менеджеров имеет значение, число воркеров — нет:
docker node ls
Столбец MANAGER STATUS покажет, кто из менеджеров сейчас Leader, Reachable или Unreachable — второе слово буквально описывает потерю связности с точки зрения кворума. Сравнение того, как Swarm и k3s ведут себя именно при потере кворума менеджеров, — в статье «k3s против Docker Swarm: что выгоднее и когда»; а частые проблемы самого Swarm, включая потерю кворума, разобраны в «Docker Swarm на сервере: частые ошибки и решения».
Redis Sentinel для мониторинга мастер-реплики использует свой параметр quorum в конфиге — минимальное число «сторожей»(sentinel), которые должны согласиться, что мастер недоступен, прежде чем инициировать переключение на реплику:
sentinel monitor mymaster 10.0.0.5 6379 2
Последняя цифра здесь — как раз кворум: при трёх Sentinel-процессах порог 2 означает, что решение о неисправности мастера принимается только при согласии как минимум двух из трёх наблюдателей, а не по мнению одного, который сам может ошибаться из-за собственных сетевых проблем.
Разные названия, разные протоколы, но идея одна и та же: подсчёт голосов от списочного состава, порог «больше половины», блокировка меньшинства.
Witness-узел: как получить третий голос без третьего полноценного сервера
Часто ресурс, который жалко тратить на кластер, — это не сам факт третьего узла, а его стоимость: третий полноценный сервер с процессором, памятью и диском ради того, чтобы просто участвовать в голосовании, кажется расточительством, если реальная нагрузка вполне помещается на двух машинах.
Решение придумано давно — witness-узел (в терминологии Proxmox/corosync — QDevice, у других систем встречаются термины arbiter или tie-breaker). Это лёгкий узел, который не хранит данные и не запускает виртуальные машины или сервисы — его единственная задача — отвечать на вопрос «ты меня видишь?» и тем самым участвовать в подсчёте голосов. Именно так на двух полноценных узлах можно получить честный трёхголосый кворум, не покупая третий сервер того же класса.
Для Proxmox схема разворачивается так: на отдельной лёгкой машине (подходит даже минимальный VPS в третьей локации — что физически важно, иначе witness окажется в той же сети, что и один из основных узлов, и не защитит от разрыва связи именно с этим узлом) поднимается пакет corosync-qnetd, а на обоих боевых узлах — corosync-qdevice, после чего он регистрируется командой:
pvecm qdevice setup <IP-адрес-witness-узла>
После настройки pvecm status покажет уже не 2, а 3 голоса в Expected votes, и кластер из двух «тяжёлых» узлов получает ту самую защиту от split-brain, которую иначе давал бы только третий боевой сервер. Похожая идея есть и в других экосистемах: у MongoDB — arbiter-инстанс в реплика-сете, у VMware vSAN — witness appliance, у некоторых конфигураций Galera Cluster — garbd (Galera Arbitrator Daemon).
Важная оговорка: witness-узел решает проблему кворума, но не проблему производительности и объёма хранения — если один из двух боевых узлов действительно выйдет из строя, второй должен будет тянуть всю нагрузку в одиночку. Witness даёт правильное поведение при разрыве связи, а не бесплатную замену полноценного третьего сервера с реальными ресурсами.
Практические рекомендации: когда 2 узла допустимы, а когда нужны честные 3
Свести теорию к практике можно в несколько правил:
- Для продакшена с автоматическим failover — 3 узла или 2 узла + witness минимум. Без этого при сбое сети вы получаете либо полную остановку кластера, либо, если система вообще не настроена на честный кворум, split-brain с повреждением данных.
- Витнесс-узел размещайте в третьей независимой сети/локации, а не рядом с одним из боевых узлов — иначе при отказе именно того сегмента сети, где стоит witness вместе с одним из узлов, кворум опять не наберётся честно.
- Нечётность важна только для голосующих узлов, а не для всех машин кластера. В Kubernetes/k3s это control-plane с etcd — их держат в 3 или 5 штук, рабочие ноды можно добавлять сколько угодно. В Docker Swarm аналогично: нечётность важна для менеджеров, воркеры вне этой арифметики.
- Двух узлов без witness достаточно только там, где нет реального требования к кворуму — например, репликация БД с ручным переключением, где вы сознательно контролируете, что старый мастер не ожил одновременно с новым.
- Не путайте отказоустойчивость с резервным копированием. Кворумный кластер защищает от простоя при отказе узла, а не от испорченных данных или случайного
DROP TABLE— это отдельный уровень защиты.
Если нужно на цифрах прикинуть, во что обходится каждая следующая ступень отказоустойчивости — от одиночного сервера до полноценного HA-кластера с балансировщиком, — подробный разбор с оценками стоимости есть в статье «Стоимость отказоустойчивости по уровням».
Нужен сервер под эту задачу?
Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.
Арендовать серверНужны сами нейросети для контента?
Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.
Частые вопросы
Если у меня всего 2 сервера, можно ли вообще собрать HA-кластер?
Технически да, но без witness-узла или третьего арбитра честного кворума не получится — при разрыве связи между двумя узлами система не сможет математически определить большинство. Практический вариант — добавить лёгкий witness на третьей независимой площадке (для Proxmox это corosync-qdevice на минимальном VPS), либо сознательно использовать конфигурацию без автоматического failover и переключаться вручную.
А если взять 4 или 6 узлов вместо 3 или 5, будет только лучше?
Нет — как показано в таблице выше, кластер из 4 узлов переживает отказ ровно того же одного узла, что и кластер из 3, но при этом появляется риск разрыва связи ровно пополам (2 на 2) без явного большинства ни у одной стороны. Чётное число узлов — это дополнительная стоимость без выигрыша в устойчивости к разрыву сети; если бюджет позволяет 4 узла, разумнее сразу брать 5.
Кворум — это то же самое, что и HA (высокая доступность)?
Нет, кворум — это лишь один из механизмов, на которых строится HA. Сам по себе кворум отвечает только на вопрос «какая часть кластера имеет право принимать решения», а конкретные действия при отказе узла (перезапуск виртуалки на другом узле, promote реплики в мастера, переключение трафика) — это уже отдельная логика HA-менеджера, которая использует результат голосования по кворуму как входные данные.
Что произойдёт с виртуалками и сервисами, если кластер потеряет кворум?
Узел в меньшинстве переходит в защитный режим: HA-менеджер отказывается запускать или перезапускать ресурсы, а в некоторых конфигурациях узел настроен на самостоятельную перезагрузку (fencing/watchdog), чтобы гарантированно убрать себя из игры. Уже запущенные процессы, как правило, продолжают работать — блокируется именно принятие новых решений.
Можно ли временно понизить требования к кворуму на время планового обслуживания узла?
Да, почти везде есть ручное переопределение ожидаемого числа голосов (в corosync — pvecm expected <N>), но это осознанное временное отключение защиты, а не постоянная настройка — оставлять его надолго значит добровольно вернуться в ситуацию без честного кворума.
Обсудить статью, задать вопрос или начать новую тему
Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.
Перейти в сообщество →