Потоковое аудио через MQ (масштабируемость)

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

Описание проблемы: я хочу доставить данные конкретной задачи от нескольких производителей конкретному потребителю, работающему над задачей (оба являются контейнерами докеров, запущенными в k8s). Связь много ко многим - любой производитель может создать пакет данных для любого потребителя. Каждый потребитель обрабатывает ~ 10 потоков данных в любой момент, в то время как каждый поток данных состоит из 100 из 160 байт сообщений в секунду (от разных производителей).

Текущее решение: в нашем текущем решении каждый производитель имеет кэш значений пары задача: (IP: PORT) для потребителей и использует пакеты данных UDP для прямой отправки данных. Он хорошо масштабируется, но довольно запутан в развертывании.

Вопрос: Можно ли это реализовать в виде своего рода очереди сообщений (Kafka, Redis, rabbitMQ ...)? Например, наличие канала для каждой задачи, по которому производители отправляют данные, а потребитель - хорошо их потребляет? Сколько потоков можно было бы обработать для MQ (я знаю, что это будет отличаться - предложите лучшее).

Изменить: возможно ли создание 1000 потоков, равных 100 000 сообщений в секунду? (пропускная способность на 1000 потоков - 16 Мбит / с)

Редактировать 2: фиксированный размер упаковки - 160 байт (опечатка)


person Petr Synek    schedule 07.03.2021    source источник


Ответы (2)


Если вам не нужна постоянная дисковая память, даже не смотрите в сторону брокера сообщений. Вы просто добавляете одну проблему к другой. Прямой сетевой код - это правильный способ решить проблему трансляции звука. Теперь, если ваш код запутан и вам нужна упрощенная модель программирования, хорошей альтернативой сокетам является библиотека ZeroMQ. Это даст вам все функции MessageBroker, о которых вы заботитесь: a) дискретный обмен сообщениями вместо потоков, b) возможность обнаружения клиента; не переборщив с другим программным слоем.

Когда дело доходит до осуществимости: 100 000 сообщений в секунду с сообщением 160 Кбайт - это большой объем данных, и это составляет 1,6 Гбит / с даже без какого-либо протокола обмена сообщениями поверх него. В целом Kafka обеспечивает пропускную способность небольших сообщений, поскольку он группирует сообщения на многих уровнях. Знание этой устойчивой производительности Kafka обычно ограничивается скоростью диска, поскольку Kafka специально написан таким образом (самый медленный компонент - это диск). Однако ваши сообщения очень большие, и вам нужно писать и читать сообщения одновременно, поэтому я не вижу, чтобы это произошло без установки большого кластера, поскольку ваша проблема заключается в фактической пропускной способности данных, а не в количестве сообщений.

Поскольку ваши данные ограничены, даже другое классическое программное обеспечение MQ, такое как ActiveMQ, IBM MQ и т. Д., Действительно может очень хорошо справиться с вашей ситуацией. В целом классические брокеры гораздо более болтливы, чем Kafka, и не могут попасть в поток сообщений Kafka при обработке небольших сообщений. Но пока вы используете большие непостоянные сообщения (и правильную конфигурацию брокера), вы можете ожидать от них достойной производительности в мегабитах в секунду. Классические брокеры при правильной настройке будут напрямую подключать сокет производителя к сокету потребителя, не затрагивая диск. Напротив, Kafka всегда сначала сохраняется на диске. Так что у них даже есть некоторые плюсы латентности по сравнению с Kafka.

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

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

person Talijanac    schedule 08.03.2021
comment
Извините, я имел в виду 160b, а не поток 16kb / s: D В любом случае причина, по которой я смотрю в этом направлении, заключается в том, что довольно сложно направлять пакеты RTP через внутренние NAT k8s. Не говоря уже об открытии портов на контейнерах, сложно. - person Petr Synek; 08.03.2021
comment
Я обязательно посмотрю на zeroMQ, спасибо (все равно не могу проголосовать - недостаточно очков) - person Petr Synek; 08.03.2021

Базовый подход

С точки зрения Kafka, каждый поток в вашей проблеме может соответствовать одной теме в Kafka, и поэтому для каждой темы существует одна пара производитель-потребитель.

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


Альтернативный подход

В качестве альтернативы, лучший способ - сопоставить несколько потоков с одной темой, где каждый поток разделен ключом (например, вы используете комбинацию IP: Port), а затем иметь несколько потребителей, каждый из которых подписывается на определенный набор разделов, как определено ключ. Разделы - это точка масштабируемости в Kafka.

Против: Хотя вы можете увеличить нет. разделов, вы не можете их уменьшить.


Тип данных имеет значение

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

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

Некоторые моменты, которые следует учитывать:

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

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

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

person JavaTechnical    schedule 08.03.2021
comment
Спасибо за ответ, не могли бы вы оценить, сколько одновременных потоков я могу пройти? Возможны ли 1000 потоков, равных 100 000 сообщений в секунду? - person Petr Synek; 08.03.2021