Как обращаться с переупорядоченным RPC в плоту
При реализации алгоритма Рафта я обнаружил, что есть ситуация, которая, я думаю, может или не может нанести вред кластеру.
Разумно предположить, что некоторые AppendEntriesRPC от Leader получены с переупорядочением (сетевая задержка или другие причины). Считайте, что Лидер отправляет сердцебиение AppendEntriesRPC на узел A, с prev_log_index = 1
, а затем отправьте еще один AppendEntriesRPC с записью 2, а затем произойдет сбой (я гарантирую, что это произойдет немедленно с помощью обратного вызова в моем тесте). Если два RPC обрабатываются в порядке их отправки, запись 2 будет успешно вставлена. Однако, если RPC сердцебиения задерживается, то узел A сначала вставит запись 1 и ответит Лидеру. Затем идет задержанное сердцебиение, узел A сотрет запись 2, потому что конфликт входа с лидером prev_log_index = 1
, Таким образом, peer A по ошибке удаляет запись в журнале.
Если копнуть немного глубже, если Лидер не падает сразу, это исправит это? Я думаю, что если узел A правильно отреагирует на задержку сердцебиения, Лидер обнаружит и исправит это в некоторых последующих RPC.
Тем не менее, что, если ответ сверстника А на запись 2 приведет к commit_index
продвижение? В этом случае равный А голосует за продвижение commit_index
до 2, даже при том, что у него фактически нет входа 2. Таким образом, может быть недостаточно голосов для этого продвижения. Когда Leader падает, узел с меньшим количеством журналов будет выбран в качестве Leader. И я сталкиваюсь с такой ситуацией во время тестирования.
Мой вопрос:
- Правильно ли мои рассуждения?
- Если переупорядочить RPC реальная проблема, как я должен решить это? Является ли индексирование и кэширование всех RPC и принудительно обрабатывать их один за другим хорошим решением? Мне было трудно реализовать в gRPC.
1 ответ
Плот предполагает протокол упорядоченного потока, такой как TCP. То есть, если сообщение приходит не по порядку, оно буферизуется до тех пор, пока не прибудет его предшественник. (Именно по этой причине существует протокол TCP: поскольку каждый отдельный пакет может проходить по отдельным маршрутам между серверами, и существует высокая вероятность появления сообщений, выходящих из строя, а большинство приложений предпочитают простоту строгого порядка.)
Другие протоколы, такие как обычный старый Paxos, могут работать с сообщениями не по порядку, но, как правило, намного медленнее, чем Raft.