Москва: проверенные б/у ноутбуки с гарантией и проверкой перед оплатой
+7 906 722-94-45

Главная → Статьи → Gossip protocol: эпидемический протокол обмена состоянием

Gossip protocol: как узлы узнают состояние кластера без центра

Gossip-протокол: SWIM и membership, скорость распространения O(log N), детекция отказов, настройки в Cassandra, Consul и Redis Cluster.

Прямой ответ

Gossip (эпидемический протокол) — способ распространения информации в кластере без центрального координатора: каждый узел периодически выбирает несколько случайных соседей и передаёт им своё представление о состоянии кластера. Те, в свою очередь, передают дальше. Информация расходится экспоненциально — за O(log N) раундов её узнают все узлы, при этом отказ любого узла не останавливает распространение.

Что обычно распространяют gossip-ом:

  • Membership — кто жив, кто подозревается, кто исключён (протокол SWIM: ping → ping-req через посредника → suspect → dead).
  • Метаданные схемы и топологии — в Cassandra это информация о ключевых пространствах, токенах и версии схемы.
  • Состояние реплик и векторы версий — какие версии данных где лежат, что нужно для read repair.
  • Конфигурация сервисов — в Consul и Serf так распространяются события join/leave и пользовательские сообщения.

Ключевые свойства:

  1. Отказоустойчивость. Нет единой точки отказа: потеря части узлов замедляет, но не останавливает распространение.
  2. Масштабируемость. Нагрузка на узел не зависит от размера кластера — он общается с фиксированным числом соседей за раунд.
  3. Сходимость в конечном счёте. Gossip не даёт мгновенной согласованности: в разные моменты разные узлы могут видеть разное состояние. Это типичная eventual consistency, а для сходящихся структур используют CRDT.
  4. Версионирование. Каждое утверждение о состоянии несёт счётчик/heartbeat-версию, поэтому более старая информация не перетирает новую.

Практика: настройки и наблюдения

Cassandra. Gossip работает раз в секунду (gossip task), обмениваясь состоянием с одним живым узлом, одним недостижимым и (иногда) новым узлом:

-- состояние узлов и схема
nodetool status
nodetool gossipinfo
-- проверка версий схемы на узлах
nodetool describecluster

Расхождение schema versions в describecluster — типичный симптом незавершённой миграции: узел с устаревшей схемой будет отклонять запросы.

Consul / Serf. Используют SWIM поверх UDP; важны параметры gossip_interval, gossip_nodes, retransmit_mult, suspicion_mult. Увеличение gossip_interval снижает трафик, но замедляет детекцию отказов.

Redis Cluster. Обмен сообщениями MEET/PING/PONG по шине кластера; состояние слотов расходится gossip-ом, поэтому после решардинга нужно дождаться сходимости, прежде чем оценивать «правильность» топологии.

Практические рекомендации:

  1. Не путайте «узел умер» и «узел подозревается». SWIM специально вводит состояние suspect, чтобы не исключать узлы из-за одной потери пакета. Алерт стоит поднимать на устойчивом состоянии dead, а не на каждом suspect.
  2. Следите за размером сообщений. Gossip переносит метаданные; если в сообщение попадает полезная нагрузка (например, большие пользовательские события), трафик растёт квадратично по эффекту.
  3. Разнесение по стойкам. Случайный выбор соседей хорошо перемешивает информацию, но для детекции отказов полезно иметь «seed»-узлы в разных зонах.
  4. Метрики. Число suspect/dead-переходов, длительность сходимости схемы, размер gossip-сообщений — базовый набор для дашборда; как их снимать — в статье про инструментацию приложения.

Практический сценарий: узел «мигает» и кластер штормит

Контекст: Cassandra из шести узлов, периодически один узел помечается DN, затем снова UN.

  1. Симптом. В логах повторяющиеся InetAddress ... is now DOWN / is now UP, клиенты получают таймауты, часть запросов ретраится.
  2. Гипотезы. (а) Реальные потери пакетов между узлами; (б) перегрузка CPU — gossip-таск не успевает выполниться вовремя; (в) GC-паузы, из-за которых узел не отвечает на ping.
  3. Проверка. nodetool gossipinfo показывает скачущие heartbeat-версии; nodetool tpstats — очереди задач; GC-логи — паузы; ping/mtr между узлами — потери. Дополнительно смотрим загрузку ОС инструментами из статьи про диагностику производительности Linux-сервера.
  4. Исправление. Устраняем причину пауз (настройка GC, лимиты), при необходимости увеличиваем допуски детекции, но не «отключаем gossip». Отдельно проверяем, что клиентские ретраи идемпотентны — см. идемпотентность API.
  5. Проверка сходимости. После стабилизации сверяем describecluster на всех узлах и убеждаемся в единой версии схемы.

Результат: «мигание» прекратилось, шторм остановлен. Вывод: gossip корректно сообщает о проблемах узла, но сам по себе их не создаёт — причину почти всегда нужно искать в задержках и потерях, а не в параметрах протокола.

FAQ

Чем gossip отличается от heartbeat с центральным монитором? Heartbeat «звезда» даёт одну точку отказа и нагрузку, растущую с размером кластера. Gossip децентрализован: каждый узел знает только соседей, а картина складывается из множества независимых обменов. Плата — задержка сходимости и возможность кратковременных расхождений.

Как быстро информация доходит до всех узлов? В идеализированной модели — за O(log N) раундов: на первом шаге знают 2 узла, на втором 4, на третьем 8 и так далее. Для 1000 узлов это около десяти раундов, то есть порядка десяти секунд при раунде в одну секунду.

Можно ли строить на gossip строгую согласованность? Нет. Gossip обеспечивает распространение, но не порядок и не атомарность решений. Для согласованных решений поверх него добавляют кворум-протоколы (Raft, Paxos) или внешнее согласованное хранилище; см. Raft.

Почему SWIM использует посредников (ping-req)? Чтобы отличить «узел недоступен» от «у меня с ним плохая связь». Прежде чем объявить узел suspect, инициатор просит несколько случайных участников пингануть цель напрямую. Это резко снижает число ложных исключений при локальных сетевых проблемах.

Источники: SWIM paper (Cornell), Cassandra docs (Dynamo architecture), Redis Cluster spec — ссылки в шапке.