Ключевые факты
- Большинство библиотек консенсуса (Raft, Paxos) рассматривают конечный автомат как абсолютно черный ящик.
- Если лидер падает после выполнения побочного эффекта, но до его фиксации, возникают дубликаты.
- Chr2 использует реплицируемый «исходящий ящик»: побочные эффекты хранятся как «ожидающие» в реплицируемом состоянии.
- Дюра́бельное ограждение (Durable Fencing) использует манифест для предотвращения действий «зомби»-лидеров.
- Chr2 — это CP-система, которая ставит безопасность выше доступности.
Краткое содержание
Стандартные библиотеки консенсуса, такие как Raft и Paxos, обычно игнорируют то, что происходит после фиксации записи в журнале. Они рассматривают конечный автомат как черный ящик, полагая, что приложение берет на себя остальное. Это предположение нарушается, когда приложение должно инициировать внешние действия, такие как списание средств с кредитной карты, вызов веб-хука или отправка электронного письма. Если лидер падает после выполнения действия, но до завершения фиксации, система часто теряет информацию об операции. Когда новый лидер берет на себя управление, он может повторно выполнить ту же команду, что приведет к дублированию побочных эффектов.
Чтобы решить эту проблему, была разработана новая библиотека под названием Chr2, которая рассматривает безопасные сбои побочных эффектов как основную функцию, а не второстепенную задачу. Основная философия заключается в том, чтобы обеспечить, чтобы побочные эффекты не просто логировались, а управлялись через строгий жизненный цикл исполнения. Библиотека вводит механизм реплицируемого исходящего ящика (Replicated Outbox). Вместо немедленного выполнения побочные эффекты хранятся как « ожидающие» элементы внутри реплицируемого состояния. Выполнение строго контролируется; только активный лидер имеет право выполнять эти эффекты, и он должен делать это под специальным токеном ограждения.
Предотвращение «зомби»-лидеров — старых лидеров, которые возвращаются в сеть и пытаются действовать, — имеет критическое значение. Chr2 использует для этого Дюра́бельное ограждение (Durable Fencing). Файл манифеста сохраняет номер высшего «вида» (view) с использованием атомарных операций (tmp+fsync+rename). Это гарантирует, что старый лидер не сможет проснуться и выполнить устаревшие эффекты. Для обеспечения согласованности при восстановлении или повторном проигрывании система предоставляет Детерминированный контекст. Код приложения получает детерминированное начальное значение генератора случайных чисел (RNG) и время блока непосредственно из журнала, что гарантирует идентичность переходов состояния при повторном проигрывании. Наконец, журнал предварительной записи (WAL) является строгим: записи защищены CRC и связаны хешами. Если обнаружена коррупция, система останавливается, а не пытается угадать данные. Хотя эти меры обеспечивают высокую безопасность, система явно спроектирована как CP-система (Согласованность/Терпимость к разделению), ставящая безопасность выше доступности и допускающая, что побочные эффекты будут выполняться хотя бы один раз, а не строго один раз.
Проблема стандартного консенсуса
Алгоритмы консенсуса являются основой распределенных систем, позволяя нескольким серверам согласовывать последовательность команд. Библиотеки, реализующие Raft и Paxos, широко используются для этой цели. Однако эти библиотеки обычно фокусируются исключительно на репликации журнала и согласованности. Они гарантируют, что все узлы согласны с порядком операций, но не управляют последствиями этих операций. Это часто описывается как рассмотрение конечного автомата как «черного ящика». Слой консенсуса передает команду слою приложения и считает свою работу выполненной.
Такое разделение ответственности становится проблематичным, когда приложению необходимо взаимодействовать с внешним миром. Обычные операции включают:
- Списание средств с кредитной карты клиента.
- Отправку уведомления по электронной почте.
- Инициирование веб-хука внешнему сервису.
Опасность возникает во время сбоя лидера. Представьте, что лидер получает команду «Списать $50». Он передает это приложению, которое обращается к платежному шлюзу и успешно списывает средства. Однако, прежде чем лидер успевает реплицировать запись журнала большинству последователей и зафиксировать ее, он падает. Последователи не знают, что операция была выполнена. Когда избирается новый лидер, он видит незафиксированную запись и выполняет ее снова. Клиент списывает средства дважды. Это «ложь» строго однократного выполнения, упомянутая в документации: истинное гарантируемое выполнение один раз чрезвычайно сложно обеспечить на уровне консенсуса без помощи приложения или специализированного механизма.
Как Chr2 обеспечивает безопасность при сбоях
Chr2 подходит к проблеме, интегрируя управление побочными эффектами непосредственно в механизм консенсуса. Она отходит от модели черного ящика к системе, где побочные эффекты являются первоклассными гражданами. Библиотека достигает этого с помощью комбинации четырех конкретных технических механизмов, предназначенных для совместной работы.
Реплицируемый исходящий ящик
Фундаментальный сдвиг в Chr2 — это введение реплицируемого исходящего ящика (Replicated Outbox). Вместо немедленного выполнения побочного эффекта и надежды на фиксацию записи в журнале, Chr2 сохраняет намерение как состояние «ожидания» в реплицируемом журнале. Это означает, что запрос на выполнение действия реплицируется на другие узлы так же, как и любое другое изменение состояния. Однако само выполнение декуплировано от начальной записи журнала. Только назначенный лидер имеет право выполнять эти ожидающие эффекты, и он делает это под защитой токена ограждения. Этот токен выступает в качестве доказательства полномочий, гарантируя, что только текущий действительный лидер может инициировать внешние действия.
Дюра́бельное ограждение и предотвращение зомби
Значительный риск в распределенных системах — это «зомби»-лидер. Это происходит, когда лидер отключается от сети, считается мертвым, а затем внезапно появляется снова. Если он все еще считает себя лидером, он может попытаться выполнить операции, которые уже были обработаны его преемником. Chr2 предотвращает это с помощью Дюра́бельного ограждения (Durable Fencing).
Система поддерживает файл манифеста, который записывает высший номер «вида» (по сути, срок полномочий лидера). Когда лидер меняется, этот манифест обновляется с использованием определенной последовательности операций: записи во временный файл, принудительной синхронизации с диском (fsync) и затем переименования файла в окончательное имя (атомарная замена). Это гарантирует, что даже при потере питания во время обновления состояние останется согласованным. Старый лидер, пытающийся проснуться, обнаружит, что его номер вида ниже, чем у сохраненного манифеста, и откажется выполнять эффекты.
Детерминированный контекст для повторного проигрывания
Повторное проигрывание журнала является стандартным требованием для восстановления после сбоев. Однако побочные эффекты часто зависят от таких переменных, как метки времени или случайные числа. Если они изменятся при повторном проигрывании, конечный автомат может оказаться в другом состоянии, чем раньше. Chr2 решает эту проблему, предоставляя Детерминированный контекст. Когда коду приложения нужно выполнить действие, он получает конкретные входные данные от слоя консенсуса:
- Детерминированное начальное значение генератора случайных чисел (RNG).
- Точное время блока из журнала.
Поскольку эти входные данные фиксируются историей журнала, повторное проигрывание журнала всегда будет давать одинаковый результат. Это гарантирует переходы состояния 1:1.
Строгий журнал предварительной записи (WAL)
Целостность данных имеет первостепенное значение. Chr2 использует Строгий WAL. Каждая запись, записанная в журнал, защищена циклическим избыточным кодом (CRC) и связана хешем с предыдущей записью. Это создает проверяемую цепочку данных. Если в середине журнала обнаружена коррупция, система останавливается немедленно, не пытаясь угадать, какими могли быть отсутствующие данные. Этот подход «отказ в работе» (fail-closed) предотвращает распространение коррупции данных по системе.




