Внедрение распределенного сервиса n-Producers / 1-Consumer для критически важной системы

Aug 17 2020

Я пытаюсь реализовать распределенную версию с несколькими производителями / 1 потребителями для критически важной системы. Ищу хорошие альтернативы текущему подходу, основанному на СУБД.

Проблема

Система состоит из нескольких (50+) производителей, которые непрерывно производят тысячи экземпляров в секунду. Каждый экземпляр имеет четко определенную плоскую структуру с метками времени. Каждый экземпляр хранится производителями в единой очереди.

С другой стороны, у меня есть потребитель, который использует экземпляры в режиме FIFO.

Производители и Потребители работают на разных машинах, соединенных частной сетью TCP / IP.

Для полноты картины есть два строгих требования.

  1. Потребитель не может потреблять один и тот же ресурс дважды. Это ошибка.
  2. Каждый ресурс должен быть потреблен потребителем. Если ресурс упущен, это потеря

Кроме того, решение должно работать на серверах Linux и Windows.

Текущий подход

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

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

Модель транзакций сервера базы данных / JDBC позволяет контролировать вставки / удаления, чтобы избежать повреждения очереди.

Этот текущий подход работает хорошо, но:

  1. Добавляет накладные расходы на обслуживание всего сервера реляционной базы данных для задачи, в которой не требуется отношения данных;
  2. Сервер реляционной базы данных должен соответствовать критически важным требованиям, чего трудно достичь при некоторых реальных настройках, когда экземпляр сервера базы данных не выделен.

Альтернативы

Здесь я перечисляю некоторые альтернативы существующему подходу к шине данных сервера реляционной базы данных:

Выделите легкий сервер реляционной базы данных

Кажется, это самый простой подход: использовать специальный легкий сервер реляционной базы данных, такой как HSQLDB, Apache Derby или H2.

Плюсы

У них значительно меньше накладных расходов на обслуживание по сравнению с СУБД, такой как MS SQL Server, Oracle DB Server или даже MySQL. Кроме того, требуется меньше изменений кода и тестов, поскольку они в основном представляют собой механизмы SQL, подобные тем, которые используются в текущем решении.

Минусы

Это серверы реляционных баз данных, поэтому оказывается, что для выполнения задачи, не связанной с отношениями, все еще существуют некоторые накладные расходы. Другой момент - аспект критической миссии. Мы используем Derby DB внутри компании на протяжении многих лет для наблюдения за системой в реальном времени как во встроенном, так и в сетевом режимах. Он отлично работает, ни сбоев, ни повреждения данных. Однако объем транзакций в секунду для этого нового использования выше.

Redis сервер

На первый взгляд Redis идеально подходит для этого варианта использования. В памяти, быстро, без лишних затрат на взаимосвязь данных, просто. Широко используется в качестве базы данных и считается надежным. Но не для Windows. Как сказано в документации, Redis для Windows не рекомендуется . Не порт Microsoft Windows больше не поддерживается , последние даты выпуска 2016 года так прикрепления Redis к системе выглядит не перспективны.

Реализация решения с нуля

В конце концов, это проблема производителя и потребителя. Реализация сетевой службы с использованием TCP или чего-то более элегантного, такого как Camel, с использованием внутренней параллельной очереди плюс некоторый локальный механизм сохранения будет затратным по времени, изобретать колесо, но это все же вариант.

Это альтернативы, которые мы пока рассматриваем. Буду признателен, если кто-то может дать некоторое представление или рекомендацию.

Ответы

2 LieRyan Aug 18 2020 at 02:08

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

Некоторые подходы, такие как ZeroMQ, могут выполняться без посредника сообщений, что означает, что производители и потребители общаются напрямую, не нуждаясь в другой службе или базе данных для организации / посредничества очереди. Преимущество отсутствия брокера состоит в том, что его намного проще управлять в оперативном режиме, чем при посредничестве очередей сообщений, а также проще понимать, масштабировать и настраивать, но основным недостатком является отсутствие услуг, обычно предоставляемых брокерами, поэтому, если участник в автономном режиме, сообщения могут быть потеряны. Если вам нужно, чтобы сообщение было надежно обработано, вам нужно спроектировать своих производителей так, чтобы они могли обрабатывать повторную отправку, если потребитель недоступен, вам необходимо добавить механизм для подтверждения успешной доставки, а потребителю нужно быть идемпотентным (иметь возможность обнаруживать повторяющиеся сообщения и отбрасывать их). Основное преимущество отсутствия брокера заключается в том, что вы можете реализовать столько или меньше брокерских функций, сколько требуется вашему приложению, поэтому вы не привязаны к конкретному поведению брокера.

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

есть еще некоторый уровень накладных расходов для выполнения задачи без взаимосвязей

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