Как защитить хранилище от записи старого лидера после восстановления сетевого разделения?
Используйте fencing token — монотонно возрастающий маркер эпохи лидера. При каждой выдаче лидерства координатор увеличивает токен, а хранилище принимает запись только от владельца токена, который не старше последнего принятого.
Одного тайм-аута аренды недостаточно: старый лидер может не узнать о потере лидерства из-за сетевого разделения или длительной паузы и продолжить запись. Проверка токена выполняется на стороне хранилища, поэтому устаревший лидер получает отказ даже после восстановления связи.
Распределённые блокировки и leases появились как способ выбрать одного активного владельца ресурса на ограниченный срок. Это решало проблему конкурентного доступа, но не устраняло риск, что владелец временно перестанет взаимодействовать с координатором, а затем продолжит работу с устаревшим правом.
Такой риск особенно заметен при сетевых разделениях, остановках виртуальной машины, паузах сборщика мусора или перегрузке процесса. Поэтому к аренде добавили защиту самого ресурса от команд старой эпохи — fencing.
Пусть узел A получил право быть лидером и начал запись в хранилище. Затем между A и координатором возникло сетевое разделение, координатор назначил лидером узел B, а A из-за задержки или паузы ещё не знает об этом.
Если хранилище принимает команды только на основании локального факта «A когда-то был лидером», старый узел может перезаписать данные, созданные B. Это приводит к потере обновлений, нарушению инвариантов или расхождению состояния после восстановления сети.
Координатор выдаёт каждому новому владельцу ресурса новый fencing token: например, 41, затем 42. Лидер прикладывает свой токен к каждой операции, а хранилище хранит максимальный уже принятый токен.
Операция с токеном 42 обновляет данные и фиксирует значение 42. Любая последующая операция с токеном 41 отклоняется, даже если она пришла позже и от узла, который формально ещё считает себя лидером. Таким образом, порядок эпох проверяется там, где происходит опасное изменение состояния.
Токен должен быть связан с операцией записи атомарно: нельзя сначала проверить его, а затем независимо выполнить запись, иначе две конкурентные операции могут обойти проверку. Хранилище также должно действительно обеспечивать сравнение токенов; передача токена только между клиентами без принудительной проверки не даёт защиты.
Lease и fencing решают разные задачи. Lease ограничивает период, в течение которого координатор считает узел владельцем, а fencing не позволяет старому владельцу воздействовать на ресурс после утраты права. Надёжная схема обычно использует оба механизма: lease для обнаружения устаревшего лидера и токен для защиты записи.
Требуется также надёжная выдача токенов: два владельца не должны получить один и тот же номер для разных эпох. Если хранилище не умеет проверять токен, нужен отдельный слой, который является единственной точкой допуска операций и сам гарантирует fencing.
Сервис назначает лидера для обработки одного платежного потока. Лидер A получил lease и токен 17, но затем надолго завис из-за паузы виртуальной машины. Lease истёк, координатор назначил лидером B и выдал ему токен 18.
Вариант с одним lease опасен: после возобновления A может отправить старую команду списания или изменить статус платежа. Вариант с повторной проверкой лидерства перед каждой операцией уменьшает риск, но не закрывает окно между проверкой и записью, а при сетевой проблеме A всё равно может использовать устаревшие данные.
Выбран вариант, при котором платежное хранилище принимает запись только вместе с токеном и атомарно отклоняет токены меньше последнего принятого. B с токеном 18 успешно обрабатывает платеж, а поздняя команда A с токеном 17 отклоняется. Система сохраняет единственного действительного автора изменений без необходимости доверять своевременной остановке старого процесса.
Нет. Тайм-аут сообщает координатору, что владелец, вероятно, потерял право, но старый процесс может не получить это сообщение и продолжить работу. Пока ресурс не проверяет fencing token, он не отличает действующего владельца от устаревшего.
На границе, через которую выполняется опасная операция над ресурсом: в хранилище, файловом сервисе, брокере или специализированном шлюзе. Проверка только в координаторе или клиентском коде недостаточна, потому что между проверкой и записью может произойти разделение сети, остановка процесса или смена лидера.
Два запроса могут одновременно увидеть допустимое значение и оба изменить данные, нарушив защиту. Поэтому проверка токена, изменение состояния и фиксация нового максимального токена должны выполняться как одна атомарная операция либо под механизмом, предоставляющим эквивалентную гарантию. Монотонность номеров сама по себе не заменяет атомарность проверки и записи.