Темы



Выбирая QuePaxa — необычный алгоритм консенсуса

Коротко сгенерировано ИИ по тексту статьи
  • Cloudflare представила Meerkat — экспериментальную службу консенсуса для внутренней глобальной плоскости управления; она использует алгоритм QuePaxa.
  • QuePaxa не требует лидера и, по словам Cloudflare, должен лучше работать при скачках задержки и разрывах связи.
  • В 2020 году частичный сбой сетевого коммутатора замедлил панель управления в 80 раз на шесть часов; запись была недоступна, но данные не потерялись.

Почему это важно: Для Meerkat простои при сбоях лидера неприемлемы, а глобальная сеть подвержена нестабильности и переменным задержкам.

Cloudflare недавно представила Meerkat — экспериментальную распределённую службу консенсуса, предназначенную для управления нашей внутренней глобальной плоскостью управления. В её основе лежит новый алгоритм консенсуса под названием QuePaxa.

QuePaxa — необычный выбор: в большинстве систем консенсуса используются хорошо зарекомендовавшие себя алгоритмы, такие как Raft, (Multi-)Paxos или репликация с метками представлений. Эти алгоритмы хорошо изучены, имеют зрелые реализации и, как правило, работают исправно.

К сожалению, распространённые алгоритмы консенсуса часто дают сбои в глобальных сетях с нестабильным подключением и переменной задержкой — например, в интернете, где работает Meerkat. Эти алгоритмы полагаются на доступность одного процесса лидера и предсказуемую задержку. Если лидер выходит из строя, работает медленнее обычного или теряет связь, вся система консенсуса замедляется или становится недоступной, пока ему не найдут замену. Для Meerkat это неприемлемо.

Глобальная среда развёртывания Meerkat привела нас к более новому алгоритму консенсуса QuePaxa, который обещает большую устойчивость к нестабильности, в значительной степени благодаря тому, что для продолжения работы ему не нужен лидер. В этой статье мы расскажем, почему выбрали QuePaxa и как работает этот алгоритм.

Что мы создаём и в чём его уникальность

Meerkat — распределённая система, в которой реплики согласуют упорядоченный журнал событий, причём каждое событие определяется алгоритмом консенсуса.

Алгоритмы консенсуса позволяют группе машин договориться об общей истине, даже если некоторые из них выходят из строя или теряют связь. Они обеспечивают важную гарантию: машины никогда не принимают противоречащие друг другу значения. Благодаря этому журналы реплик Meerkat никогда не расходятся.

Meerkat использует журнал, основанный на консенсусе, чтобы предоставлять приложениямтакие возможности, как хранилище «ключ — значение», где каждая запись в журнале — это get или put. Поскольку алгоритм консенсуса гарантирует, что журналы реплик никогда не расходятся, все они формируют одинаковое состояние «ключ — значение» (KV). К системам, основанным на консенсусе, относятся также Consul, etcd и Apache ZooKeeper.

Однако, в отличие от похожих систем, Meerkat создавался для глобального масштаба. Кластер Meerkat может быть распределён по разным континентам и соединён каналами связи, для которых часто характерна высокая и переменная задержка. Для систем консенсуса это необычная конфигурация: обычно их развёртывают в небольших локальных сетях, где действуют строгие требования к задержке.

Проблемы консенсуса в глобальном масштабе

Хотя все алгоритмы консенсуса обеспечивают согласие реплик относительно одного и того же значения, многие из них становятся непропорционально медленными или недоступными при ухудшении состояния сети (если сами машины при этом не выходят из строя). Мы убедились в этом на собственном опыте: в 2020 году из-за частичного сбоя магистрального сетевого коммутатора Cloudflare система, основанная на консенсусе, начала работать хуже, а панель управления — в 80 раз медленнее обычного. Так продолжалось шесть часов. Важно, что система не потеряла ни одного бита данных. Но до устранения проблемы она не могла выполнять запись, а это неприемлемо.

В идеале алгоритм консенсуса должен продолжать работу несмотря на скачки задержки и разрывы соединения, а не только на сбои реплик. Особенно остро эта проблема стоит в глобальном масштабе, где неполадки чаще возникают в сети, а не на наших серверах.

Рассмотрим два распространённых свойства алгоритмов консенсуса, которые могут приводить к ухудшению работы в неблагоприятных условиях сети: деструктивное взаимодействие и обнаружение сбоев. Далее мы увидим, как QuePaxa обходит обе эти проблемы.

Деструктивное взаимодействие и лидеры

Возьмём Paxos — настоящего прародителя большинства алгоритмов консенсуса. Многие алгоритмы консенсуса унаследовали структуру Paxos — как её достоинства, так и не самые удачные особенности.

Опустив массуподробностей, расскажем, как работает Paxos. В нём есть два типа процессов: предлагающие и принимающие. Если говорить абстрактно, цель системы — добиться, чтобы большинство принимающих согласилось со значением, предложенным каким-либо предлагающим. Процесс состоит из двух этапов: Prepare и Accept. На этапе Prepare любой предлагающий может отправить номер голосования большинству принимающих. Этот номер служит обещанием: принимающие согласятся только на предложения с таким же или более высоким номером голосования. Затем, на этапе Accept, предлагающий снова отправляет своё предложение вместе с номером голосования большинству принимающих. Если у большинства принимающих по-прежнему указан номер голосования этого предложения, они принимают его, и предлагающий может безопасно зафиксировать решение.

In the Prepare phase, a proposer sends a ballot numbered

Проблемы возникают, когда два или более предлагающих отправляют предложения одновременно. В частности, другой предлагающий может вклинить собственный, более высокий номер голосования между двумя этапами, блокируя все более низкие номера. Два предлагающих могут снова и снова мешать друг другу продвигаться — по сути, соперничая за принятие предложения.

There are two proposers: one red, and one blue. In the Prepare phase, the blue proposer sends a ballot numbered

Когда предлагающие соперничают и блокируют друг друга таким образом, мы говорим о деструктивном взаимодействии. Чем больше предлагающих выдвигают собственные номера голосования, тем сильнее становится этот эффект. Чем больше предлагающих действуют одновременно, тем выше вероятность, что система застрянет в цикле повторных предложений. Даже если ни одна реплика не вышла из строя и все доступны, несколько предлагающих и нестабильная сеть могут заблокировать Paxos. Формально мы говорим, что Paxos не гарантирует живучесть (то есть, что предложения в конечном итоге будут приняты), если не предположить, что в какой-то момент все сообщения будут доставлены за ограниченное время. Это предположение называется частичной синхронностью.

Чтобы избежать постоянного соперничества нескольких предлагающих, в большинстве развёрнутых алгоритмов консенсуса, таких как Raft, Multi-Paxos и репликация с метками представлений, появляется особый предлагающий —лидер. Лидер — единственная реплика, которая может вносить предложения. Сосредоточение права выдвигать предложения у одной реплики позволяет упорядочить одновременно поступившие запросы, исключает конкурирующие предложения и, кроме того, позволяет принимать решения за один сетевой обмен туда и обратно вместо двух. Пока лидер исправен, а сеть работает без сбоев, протоколы с лидером быстры.

There is a single leader replica, wearing a crown, that is the only one allowed to send proposals to other servers, called

Компромисс заключается в том, что лидер должен оставаться работоспособным и доступным. Если он выходит из строя, работает слишком медленно или теряет связь с кластером, система останавливается. Единственное решение — оставшимся репликам обнаружить сбой лидера и выбрать ему замену.

Когда восстановление лидера нестабильно

Если лидер выходит из строя, система должна восстановиться, выбрав нового. Примечательно, что именно при восстановлении лидера деструктивное взаимодействие часто возвращается в систему, основанную на лидере.

Рассмотрим Raft. В целях безопасности Raft выбирает нового лидера большинством голосов. Реплика, подозревающая, что лидер вышел из строя, объявляет себя кандидатом на лидерство и запрашивает голоса других реплик. Если более половины реплик соглашаются проголосовать за кандидата, он становится новым лидером. В противном случае назначаются новые выборы, и кандидаты пытаются снова.

Кандидатами могут стать несколько реплик — достаточно обнаружить, что лидер не работает. После этого все кандидаты могут одновременно попытаться заручиться поддержкой большинства. Проблема в том, что кандидаты будут соперничать за голоса большинства. Поэтому выборы в Raft подвержены тому же деструктивному взаимодействию, которое мы видели в Paxos: две реплики могут взаимно мешать друг другу заручиться поддержкой большинства и стать лидером. Чем больше выборов заканчиваются неудачей, тем больше реплик будут пытаться стать лидером.

There is a greyed out leader that has crashed, and four other replicas. Two replicas are candidates for leadership, and are trying to acquire a majority of votes to become leader. They both need three votes, but they each have only acquired two votes (their own and another replica’s). No candidate is elected.

Даже если лидер перестаёт работать со сбоями, выборы продолжают мешать нормальной работе системы. Это явление известно как метастабильный сбой: сбой, который сам себя поддерживает даже после устранения первоначальной причины. Двухсекундный сетевой сбой или кратковременная неисправность коммутатора могут создать впечатление, что лидер неисправен, и запустить выборы. Они могут завершиться неудачей и вызвать новые выборы. Сбой сети закончится через две секунды, но выборы могут продолжаться гораздо дольше, пока кандидаты мешают друг другу.

В идеале алгоритмам консенсуса не понадобился бы механизм восстановления: он усложняет систему, подвержен сбоям из-за взаимных помех и становится ещё одной причиной простоев.

Когда обнаружение сбоев даёт сбой

Проблема деструктивного взаимодействия при выборах лидера усугубляется чрезмерно поспешным обнаружением сбоев, особенно в глобальных сетях. Чтобы алгоритмы консенсуса с лидером могли выбрать нового лидера, реплики должны сначала обнаружить, что прежний вышел из строя. Но если реплики неверно определяют сбой лидера, система может тратить неоправданно много времени на восстановление вместо обработки запросов.

В распределённой системе, где машины соединены сетью, обнаружение сбоев в конечном счёте зависит от ожиданий. Процесс не может напрямую увидеть, что удалённый процесс вышел из строя; он может лишь заметить, пришло ли ожидаемое сообщение. Чтобы понять, исправна ли машина, нам нужен предсказуемый шаблон обмена данными — например, сигналы активности или подтверждения. Если ожидаемое сообщение не приходит вовремя, мы предполагаем, что произошёл сбой. Трудность заключается в том, чтобы правильно определить время ожидания.

В реальных сетях, особенно глобальных, сообщения не всегда приходят в ожидаемый срок. Для времени доставки сообщений нет гарантированной верхней границы. Это не значит, что сеть медленная или ненадёжная: большинство сообщений приходит в ожидаемый срок. Но внезапные всплески задержки и перебои связи могут на время, без предупреждения, увеличить срок прохождения любого сообщения по сети. Такие сети называют асинхронными.

Главная проблема асинхронных сетей в том, что если сервер не отвечает за отведённое время, мы не можем точно знать, вышел ли он из строя или просто медленно работает сеть: по сети эти два случая неразличимы. Любому практическому механизму обнаружения сбоев приходится делать предположение, основываясь на том, как долго он ждёт по сравнению с ожидаемым временем, и иногда это предположение оказывается неверным.

A user is waiting for a response from a server. The response is taking a while. The user questions whether the network is slow, or if the server crashed.

В алгоритмах с лидером именно такое предположение запускает выборы. Иногда лидер не работает; иногда его сообщения задерживаются или соединение незаметно обрывается. Прежде чем отреагировать, протокол не может понять, что именно произошло. Если реплика ошибочно считает лидера неисправным, когда на самом деле это не так, начинаются выборы, и вся система должнаостановиться. Пока лидеру не найдут замену, система не продвигается вперёд. А как мы уже видели, это может занять немало времени.

В асинхронных сетях обнаружение сбоев принципиально подвержено ошибкам, а ошибка механизма обнаружения приводит к простою.

Когда обнаружение сбоев происходит медленно

Даже если механизм обнаружения правильно определил сбой, остаются проблемы. Он реагируетна сбои, наблюдая за сообщениями в сети, поэтому скорость его реакции зависит от сетевой задержки: тайм-аут механизма не может быть меньше этой задержки. Именно поэтому Raft обычно развёртывают с тайм-аутом выборов, равным пяти — десяти временам сетевого обмена туда и обратно. Тайм-аут должен быть достаточно большим, чтобы лидер успел сообщить, что он работает, и чтобы не запускать выборы ошибочно. Тайм-аут выборов можно сделать намного меньше, но, поскольку выборы лидера полностью останавливают систему, обычно выбирают достаточно большое значение.

Для сравнения: обмен данными туда и обратно между точками, находящимися на противоположных сторонах Земли, занимает сотни миллисекунд. Если тайм-аут выборов составляет несколько таких циклов, обнаружение сбоя координатора может занять около секунды. Даже если обнаружение сбоев работает абсолютно точно, оно происходит медленно — и особенно медленно в глобальных сетях с высокой задержкой. Пока механизм не среагирует, система не работает.

Почему QuePaxa подходит лучше всего

Мы поняли, что любой алгоритм, полагающийся на строгую роль лидера или точные тайм-ауты, неизбежно будет останавливать систему консенсуса, работающую через интернет. Мы искали алгоритмы консенсуса, предназначенные для асинхронной среды, — протоколы, которым для работы не нужна стабильная сеть или точное измерение времени. Так мы нашли QuePaxa, опубликованный в 2023 году Теннаге, Бэсеску и их соавторами.

Самое примечательное в QuePaxa — его способность эффективно достигать консенсуса за один цикл обмена данными при благоприятных условиях сети и при этом плавно снижать производительность во время скачков задержки, проблем с подключением и отказов серверов. QuePaxa решает именно те проблемы, о которых мы только что говорили, благодаря трём ключевым особенностям: у него есть необязательный лидер, он полностью устраняет зависимость от обнаружения сбоев и рассчитан на конструктивное взаимодействие между предлагающими.

Как и в Paxos, в QuePaxa есть две роли: предлагающие и регистраторы. Предлагающие отправляют предложения на рассмотрение, а регистраторы выступают посредниками между ними, записывая каждое полученное предложение.

Two proposers, one blue and the other red, are opposite each other, separated by three servers labeled

Вместо того чтобы соперничать за принятие собственных предложений, предлагающие в QuePaxa совместно работают над предложением, которое поддерживают все. Для этого QuePaxa назначает предложениям приоритет в виде случайного числа. Необязательному лидеру присваивается наивысший возможный приоритет. Во время работы предлагающие отправляют предложения регистраторам, которые передают их другим активным предлагающим. Получив от регистратора предложение с более высоким приоритетом, предлагающий принимает его за своё — то есть начинает рассылать предложение с более высоким приоритетом. В целом предлагающие в QuePaxa сообща стремятся принять предложение с наивысшим приоритетом из тех, о которых им известно. Это значит, что они не могут бесконечно мешать друг другу принять какое-либо предложение.

Two proposers, one blue and the other red, are opposite each other, separated by a single recorder. The blue recorder proposes a proposal with priority

Оговорка в том, что распространить предложения может оказаться недостаточно, чтобы договориться об одном из них. В таком случае предлагающим приходится повторить попытку, причём каждая попытка составляет один раунд. Однако чем больше предлагающих отправляют предложения, тем выше вероятность, что они сойдутся на предложении с наивысшим приоритетом. Именно поэтому QuePaxa — рандомизированный алгоритм: случайно назначенные приоритеты предлагающих, не являющихся лидером, с высокой вероятностью —, но без гарантии — приведут в течение раунда к консенсусу относительно наивысшего известного приоритета. Тем не менее, если раундов будет достаточно, предлагающие гарантированно договорятся о предложении.

Один из предлагающих назначается лидером. Только он может принять решение за один цикл обмена данными. Лидер всегда выдвигает предложение с наивысшим приоритетом; если он знает, что распространил своё предложение раньше всех остальных, то может сразу принять решение. Клиенты не обязаны отправлять запросы лидеру — предложить значение может любой участник. Если лидер выходит из строя, клиенты могут продолжать отправлять запросы другим предлагающим. Лидер совершенно необязателен. Просто у него больше шансов принять решение, причём быстрее — за один цикл обмена данными.

Однако, поскольку только лидер может принять решение за один цикл обмена данными, мы хотим использовать эту возможность при каждом удобном случае. Чтобы воспользоваться этим быстрым путём и не создавать единую точку отказа, клиенты, отправляющие системе предложения, подстраховываются: они направляют запросы на предложения каждой реплике, а реплики, не являющиеся лидером, выжидают небольшой тайм-аут, чтобы лидер успел выдвинуть предложение и принять решение самостоятельно. В нашей реализации QuePaxa мы немного отступили от статьи: тайм-аут подстраховки ждут клиенты, а не реплики. Это позволяет сократить количество сообщений в сети, но результат в целом остаётся тем же.

Этот тайм-аут подстраховки сильно отличается от тайм-аутов в Raft или Multi-Paxos. Он не предназначен для обнаружения сбоев, поэтому его величина не ограничена сетевой задержкой: реплики задают его локально, и он может быть сколь угодно малым. В Raft тайм-аут в пять миллисекунд в сети с задержкой 100 миллисекунд полностью остановил бы систему. А в QuePaxa тайм-аут подстраховки в пять миллисекунд лишь увеличивает количество активных предлагающих.

Однако подстраховка не обходится бесплатно: чем больше предлагающих, тем больше предложений рассылается и тем выше вероятность, что реплики не успеют принять решение за один раунд. Поэтому подстраховка — это компромисс: мы можем быстрее реагировать на смену лидера, уменьшая тайм-аут, но при этом расходуем больше пропускной способности и можем дольше принимать решение. На такой компромисс мы готовы пойти.

Если лидер QuePaxa выходит из строя, мы можем восстановить работу настолько быстро, насколько захотим, — нас не ограничивает сетевая задержка. Так QuePaxa обходит проблему обнаружения сбоев: поскольку предложение может отправить любой участник, а не только лидер, QuePaxa заранее учитывает возможный отказ лидера с помощью подстраховки, вместо того чтобы реагировать на уже случившийся сбой.

Как QuePaxa работает изнутри

Чтобы понять, как QuePaxa обеспечивает все эти полезные свойства, рассмотрим, как именно работает этот алгоритм.  

Работа QuePaxa проходит в раундах, каждый из которых состоит из четырёх фаз. Если на последней фазе решение не принято, начинается новый раунд, и QuePaxa проходит цикл заново. В начале каждой фазы предлагающие рассылают всем регистраторам предложение, которое они приняли на данный момент. Получив ответы от большинства регистраторов, предлагающие переходят к следующей фазе. Вот общая схема:

  • Фаза 0 (предложение и принятие):  Предлагающие случайным образом выбирают приоритет, отправляют предложения регистраторам и принимают предложение с наивысшим приоритетом из тех, что получили от большинства регистраторов. Если это первый раунд и лидер знает, что его предложение первым достигло большинства регистраторов, он немедленно принимает решение.
  • Фаза 1 (распространение):  Предлагающие распространяют принятое ими предложение среди большинства регистраторов.
  • Фаза 2 (проверка и принятие решения):  Предлагающие запрашивают у большинства регистраторов предложение с наивысшим приоритетом, полученное на предыдущей фазе. Если оно совпадает с принятым ими предложением, они принимают решение.
  • Фаза 3 (перенос):  Любой предлагающий, который не смог принять решение, готовится к следующему раунду и принимает лучшее предложение из полученных от большинства регистраторов.
A flowchart shows how QuePaxa’s phases progress. The flowchart is vertically aligned. There are four major steps in the flowchart, each one representing a phase in the QuePaxa protocol. The flowchart starts with a block titled

Схема переходов между фазами и раундами QuePaxa.

Разберём несколько примеров работы алгоритма и посмотрим, как каждая фаза способствует желаемому поведению QuePaxa. В каждом примере будут участвовать два предлагающих, один из которых — лидер, и три регистратора.

Быстрый путь лидера (фаза 0): Первая фаза выполняет три важные задачи: назначает случайные приоритеты (это необходимо для обхода теоремы о невозможности FLP), проверяет, первым ли лидер заручился поддержкой большинства, и помогает предлагающим прийти к согласию, если лидеру это не удалось. Приоритет предложения лидера не выбирается случайным образом: он всегда будет наивысшим из возможных.

The image shows a message passing diagram, where time progresses from left to right. There are five lanes. At the leftmost side of the diagram, there are, ordered vertically: a blue server with a crown, labelled

В приведённом выше примере предложение лидера первым достигает большинства регистраторов и получает подтверждающие ответы. Лидер может сразу безопасно принять решение. Это может показаться рискованным, но благодаря свойству, называемому пересечением большинства, всё совершенно безопасно: любые два большинства регистраторов всегда имеют хотя бы одного общего участника. Поскольку лидер заручился поддержкой большинства, любой другой предлагающий, опрашивая большинство, неизбежно встретит предложение лидера и примет его. Так как у предложения лидера наивысший приоритет, любой другой предлагающий примет именно его. Принять какое-либо другое предложение невозможно.

Diagram with three recorders. Two of them have recorded the leader’s proposal, while the other has recorded the red proposer’s proposal. The diagram shows how any groupings of two recorders must share one recorder by adding a semi-transparent Venn diagram on top of the recorders.

Медленный путь при одновременной работе (фазы 0–3): если одновременно работают несколько предлагающих, лидер не обязательно сможет сразу принять решение. Возможно, он не успеет первым обратиться к большинству регистраторов или получит хотя бы один ответ в поддержку другого предлагающего. Рассмотрим, что происходит, когда другой предлагающий оспаривает предложение лидера.

Фаза 0:  Как показано ниже, второй предлагающий (выделен красным) первым обращается ко второму и третьему регистраторам. Быстрый путь заблокирован. Вместо того чтобы соперничать, предлагающие принимают предложение с наивысшим приоритетом из полученных от большинства регистраторов и переходят ко второй фазе. На этой фазе оба предлагающих могли бы принять предложение лидера. Для наглядности в нашем примере этого не произойдёт: мы задержим сообщения лидера.  

The blue leader proposer and the red proposer both broadcast their current proposal to every recorder. The recorders record and reply with the first proposal they receive. The leader reaches the first recorder first, while the red proposer reaches the second and third recorders first. The leader receives a majority (2) of replies, containing its own maximum priority proposal and the red proposer’s proposal with priority 1. The leader adopts the proposal with the greatest priority which is its own. The red proposer receives a majority (2) of the recorder’s replies, from the second and third recorders, both containing the red proposer’s proposal. The red proposer adopts its own proposal, since it is the one with maximum priority in the majority it received. The reply from the third recorder arrives late, not in the majority, so it isn’t considered for adoption.

Фаза 1:  Предлагающие распространяют среди большинства регистраторов предложение, которое они только что приняли на фазе 0. Регистраторы отслеживают предложение с наивысшим приоритетом из увиденных. Это простой, но важный шаг: он не позволяет протоколу позднее принять предложение с более низким приоритетом. И здесь помогает пересечение большинства: большинство, опрошенное на следующей фазе, обязательно будет включать как минимум одного регистратора, который видел принятое предложение на этой фазе. Для наглядности мы не дадим предлагающим прийти к согласию и на этой фазе: задержим сообщение лидера третьему регистратору, чтобы тот не принял предложение лидера.

The blue leader proposer and the red proposer both broadcast their current proposal to every recorder. The leader’s message to the third recorder is lost and never reaches the recorder. The first and second recorder each receive the leader’s proposal, with maximum priority, and the red proposer’s proposal, with priority 1. The third recorder only receives the red proposer’s proposal. Each recorder records the proposal with highest priority for the next phase. The first and second recorder record the leader’s proposal, while the third recorder records the red proposer’s proposal.

Фаза 2:  Теперь можно принять решение. Каждый предлагающий выясняет, набрало ли предложение с более высоким приоритетом достаточно поддержки, чтобы обойти его собственное: он запрашивает у большинства регистраторов предложение с наивысшим приоритетом из увиденных на фазе 1. Если в ответах по-прежнему преобладает его собственное предложение, предлагающий принимает решение. На нашей схеме лидер получает от большинства своё предложение и безопасно принимает решение. Другой предлагающий получает противоречивые сводки и пока не может принять решение. Как и на фазе 1, регистраторы отслеживают предложение с наивысшим приоритетом из полученных.

The blue leader and the red proposer both broadcast their current proposal to every recorder. The first two recorders recorded the leader’s proposal with maximum priority in the previous phase, while the third and final recorder recorded the red proposer’s proposal, with priority 1. Each recorder replies to the proposers with the proposal that the recorder has adopted. The leader receives a majority (2) of replies from the recorders, each carrying its proposal. Of that majority, the proposal with the maximum priority is its own, so it decides it. The red proposer receives a majority (2) of replies from the recorders, one carrying the red proposer’s proposal, and another carrying the leader’s proposal. Of those two, the proposer's own proposal does not have the greater priority, so the red proposer cannot decide, and progresses to the next phase.

Фаза 3:  Если предлагающий не принял решение на фазе 2, он переходит к завершающей фазе подготовки к следующему раунду. Предлагающие снова распространяют свои предложения и принимают лучшее из тех, что обнаружили у большинства регистраторов. Здесь оставшийся предлагающий находит принятое решение и принимает его, переходя к следующему раунду.

The red proposer fetches the recorded proposals at each recorder, all of which are the leader proposal with maximum priority. When the proposer receives a majority (2) of the replies, it adopts the proposal with the maximum value, which is the leader’s proposal.

Так задумано: если на предыдущей фазе было принято решение, это предложение будет у большинства регистраторов, и все оставшиеся предлагающие гарантированно примут его. Здесь мы снова видим, как предлагающие сотрудничают: даже если раунд не удался, они стараются прийти к согласию относительно одного предложения к началу следующего.

Переход к следующему раунду:  После четвёртой фазы предлагающие переходят к следующему раунду. На этом этапе быстрый путь лидера уже недоступен, и принять решение можно только в результате согласования на третьей фазе. Благодаря тому, что участники принимают предложения друг друга, с каждым раундом принять решение становится экспоненциально легче. Согласно статье о QuePaxa, вероятность принятия решения в каждом раунде составляет 50%, но на практике она намного выше благодаря сближению предложений.

Рассмотрев все четыре фазы вместе, мы видим, откуда берётся устойчивость QuePaxa. Первая фаза даёт лидеру возможность принять решение за один цикл обмена данными. Если этот быстрый путь не срабатывает, случайные приоритеты и принятие предложений помогают участникам прийти к согласию, а не соперничать. Вторая и третья фазы позволяют безопасно принять решение благодаря пересечению большинства, а четвёртая переносит знания предлагающих в следующий раунд на случай, если они не приняли решение.

Предлагающим не нужно обнаруживать сбой лидера, чтобы продолжать работу, а неудачный раунд не отменяет уже проделанную работу. Когда сеть работает исправно, QuePaxa работает быстро. Когда нет — QuePaxa всё равно продолжает работу.

Как QuePaxa делает возможной работу Meerkat

В ходе собственных испытаний Meerkat, для которых мы разместили серверы почти на всех континентах, мы непосредственно увидели, как QuePaxa влияет на общую производительность и доступность системы. Meerkat непрерывно обрабатывает запросы, даже если лидер выходит из строя, теряет связь или просто начинает работать медленно. Мы ни разу не видели, чтобы система полностью остановилась. Именно этого мы и хотели добиться.

Two graphs, labelled

После сбоя лидера QuePaxa переходит к принятию решений на фазе 2. Частота принятия решений снижается примерно до 65% от исходного уровня и возвращается к 100%, когда через минуту после сбоя неисправного лидера заменяют. Система ни на мгновение не останавливалась.

Скорость обработки запросов в Meerkat тоже в целом предсказуема. Большинство решений — более 95% — принимает лидер на первой фазе, благодаря чему пропускная способность остаётся довольно стабильной. В тех случаях, когда на первой фазе решение не принимается, пропускная способность ненадолго падает — максимум до трети обычного уровня. Это означает, что для принятия решения понадобилось три цикла обмена данными, то есть три фазы, вместо одного. Система замедляется, но не останавливается.

QuePaxa также позволяет нам уверенно менять реплику, которая исполняет роль лидера, пока кластер работает. Поскольку лидер не является единственным участником, принимающим решения, а предлагающие узлы взаимодействуют друг с другом, временно неоптимальный лидер ограничивает систему не так сильно, как в других алгоритмах, где неверная настройка лидера может полностью остановить работу системы. Мы можем динамически выбирать лидера среди предлагающих узлов, не слишком беспокоясь о влиянии на стабильность кластера Meerkat.

О чём мы расскажем дальше

При разработке Meerkat для глобальной сети нам пришлось заново оценить подход к распределённому консенсусу. Вместо того чтобы придерживаться привычных решений, которые не вполне соответствовали нашим требованиям, мы обратились к исследованиям, которые десятилетиями проводили академические круги и представители отрасли. В результате мы остановили свой выбор на QuePaxa.

Выбрав QuePaxa, мы пошли менее проторённым путём. Этот протокол не прошёл столь же масштабную проверку в реальных условиях, как Raft или Paxos; кроме того, мы расширяем исходную модель с остановкой при сбое, чтобы поддержать восстановление после сбоя. Для этого нужны тщательная инженерная работа и более убедительные доказательства корректности, чем обычно требуются для систем.

Именно поэтому мы формально проверяем нашу реализацию QuePaxa и Meerkat в целом, а также проводим масштабное моделирование и тестирование с инъекцией сбоев. В следующих публикациях этой серии мы расскажем, как проверяем Meerkat и реализацию QuePaxa на Rust, как тестируем сбои, которые трудно воспроизвести в промышленной среде, поделимся результатами тестов производительности и расскажем, что узнали, превращая академический протокол в промышленную систему.

Следите за новостями о Meerkat в блоге Cloudflare. А если хотите узнать больше об исследованиях Cloudflare, ознакомьтесь с нашими работами на сайте Cloudflare Research.

© Cloudflare Blog