Интегрируйте бережную реализацию распределенной системы данных (клиент, серверы) с протоколом Raft.
Итак, прежде всего, извините за мой английский. Я не носитель языка.
Вопрос в том, что у меня уже есть реализация приложения Cliente-Server с распределенными данными (3 сервера) с использованием Thrift. Теперь (последняя фаза проекта) - использовать некоторую реализацию Raft (поскольку я использую Java, опция - copycat) для репликации каждого сервера. Но Thrift создает серверы и клиентов по-своему (что-то вроде Grafosd.Client client = new...), и Grafosd генерируется Thrift. Кроме того, Thrift хранит данные в обработчике? И copycat создает сервер и клиент по-другому (что-то вроде CopycatClient client = builder.build();). а данные хранятся в StateMachine?
Так что у меня возникли сложности для интеграции обоих. Кто-то уже использовал Thrift Client-Server с какой-то реализацией протокола Raft? (не обязательно подражать, это может быть любая реализация Raft в Java).
2 ответа
Сначала вы должны спросить себя, почему на втором этапе вашего проекта используется согласованный алгоритм? Требует ли проект сильной согласованности? Рассматривали ли вы альтернативные протоколы репликации (сплетни, первичные резервные копии и т. Д.)
Независимо от того, какую реализацию Raft вы используете, способ, которым большинство реализаций моделируют состояние в системе, является конечным автоматом. Изменения в состоянии системы должны проходить через протокол Raft к лидеру и реплицироваться на последователей, а запросы о состоянии системы также должны проходить по протоколу, если вы хотите сохранить гарантии согласованности / отказоустойчивости.
Если вы хотите встроить Copycat в сервер, просто используйте LocalTransport
Что позволяет вам общаться с внутрипроцессным сервером. CopycatServer
не должен работать на удаленной машине. Совершенно реалистично и рационально встроить клиент и сервер Copycat в ваш сервер Thrift. На вашем сервере Thrift создайте CopycatServer
который содержит конечный автомат, который может представлять изменения в состоянии вашей системы, и CopycatClient
который использует LocalTransport
общаться с локальным сервером.
Вы также можете рассмотреть возможность использования Atomix, в которой AtomixReplica
обрабатывает этот локальный шаблон внедрения клиент / сервер для вас. Он также включает в себя множество примеров конечных автоматов и клиентских API.
Но, как я уже сказал, независимо от того, используете ли вы Copycat/Atomix или другую реализацию Raft, вам все равно придется моделировать изменения состояния одинаково. Каждое изменение в состоянии системы должно быть отправлено руководителю Плоту, где оно регистрируется и реплицируется для подписчиков и применяется к конечному автомату. Модель репликации конечного автомата хорошо подходит для систем с состоянием. Альтернативой для систем, которые хранят большое количество состояний или нуждаются в хранении состояний во внешней базе данных, являются постоянные конечные автоматы. Я считаю, что это то, что многие пользователи ищут в Raft. Но вы должны быть осторожны с тем, как постоянные конечные автоматы реализованы в кластере Raft, иначе вы рискуете дублировать записи.
Тем не менее, вы должны сначала определить, необходим ли такой сложный протокол, как Raft, для решения проблемы, которую вы пытаетесь решить. Сначала ответьте, что это за проблема, и что она требует от протокола репликации. Вам нужен допуск раздела? Вам нужна сильная последовательность? Вам нужна высокая доступность? Исключают ли требования по пропускной способности использование протокола на основе лидера? Почему бы просто не записать в любую внешнюю базу данных, которая реплицируется?
Я являюсь автором Copycat и Atomix. Не стесняйтесь присоединиться к нам в чате, когда ответите на некоторые из этих вопросов и определите, действительно ли это правильное направление.
Еще несколько общих замечаний по вашему вопросу с моей стороны:
Но Thrift создает серверы и клиентов по-своему (что-то вроде Grafosd.Client client = new...), и Grafosd генерируется Thrift.
Сам Thrift - это (только) механизм сериализации и RPC, который используется. Более сложные протоколы или API обычно разрабатываются поверх Thrift, используя Thrift, но не внутри Thrift. Это все равно что использовать машину для перевозки материалов на стройплощадку. Это не автомобиль, который определяет архитектуру. Автомобиль - только средство, чтобы сделать работу.
В этом отношении Thrift (или любой другой подобный механизм) является лишь инструментом в этом контексте. Я бы посоветовал сначала прояснить мысленно, к какой части головоломки относится, где можно получить максимальную отдачу от дизайна вашей системы.
Кроме того, Thrift хранить данные в обработчике?
Я бы рекомендовал всегда делать обработчики без гражданства. Если вам нужно состояние, это нормально, но храните его где-нибудь еще. Сам Thrift ничего не хранит. Это реализация обработчика, которая находится в руках разработчика на стороне сервера, который может нуждаться в хранении состояния или другой информации.