Автор статьи: Андрей Поляков

Старший разработчик в Unlimint

Что такое поток мультимедиа? Обычно это потоковое аудио или видео.

Существует множество источников таких данных:

  • Веб‑камеры, сетевые ip‑камерыю

  • Звонки из call‑центров (записываются и анализируются!)

  • Стримы игр на ютуб

  • и т. д.

Как можно передавать такие данные по сети? Существуют специальные протоколы для передачи мультимедиа данных:

  • RTSP — протокол (можно только RTP + SDP)

  • WebRTC

  • Motion JPEG over HTTP

  • WebSocket‑ы

  • и другие

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

  • источник данных (камера, АТС, стриминговый сервис, ….)

  • сервис сбора данных (обычно в ETL — это extract)

  • сервис (‑ы) анализа и преобразования данных (обычно в ETL — это load и transform)

  • сервис предоставления данных — нужен для формирования витрин данных, которые может запросить конечный пользователь через REST API (например, аналитику по звонкам, аналитику по данным с камер и т. д.)

  • постоянные хранилища для сырых данных, для аналитики, кэши

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

Верхнеуровнево архитектура такой системы может быть представлена следующим образом:

Далее каждый из компонентов системы будет рассмотрен более подробно. В качестве примера возьмем потоковый сервис видео‑аудио‑связи с постобработкой.

Вернеуровневая архитектура пайплайна обработки потока медиа‑данных примера показана на диаграмме ниже:

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

Источник данных и протоколы передачи мультимедиа

Начнем с источника данных. Как было сказано ранее, для передачи мультимедиа‑данных по сети можно использовать различные протоколы, например, RTSP или WebRTC.

RTSP — протокол прикладного уровня и испльзуется не только для передачи мультимедиа данных, но также и для более общих задач управления потоком данных, работает поверх протоколов транспортного уровня RTP и RTCP. Также для управления сеансом пользователя RTSP использует протокол прикладного уровня SDP. Более подробно все эти протоколы приведены в таблице ниже:

Уровень

Описание

Аналоги

прикладной

RTSP – управление потоком данных (установление и контроль сеанса):

OPTIONS, DESCRIBE, SETUP, PLAY, TEARDOWN, PAUSE

HTTP:

GET, POST, PUT, DELETE, …

транспортный

RTP – передача данных в реальном времени (основан на UDP)

UDP

транспортный

RTCP – контроль и синхронизация

RTCP — Википедия

UDP

прикладной

SDP (session description protocol) – описание сессии (имя сессии, время доступности сессии, URI)

Session Description Protocol — Википедия  

При использовании RTSP или RTP одним из наиболее популярных источников и обработчиков данных потока является утилита FFMPEG.

Пример запуска потока с утилитой ffmpeg:

ffmpeg 

\ -re 

\ -i media/s16le-44100hz-example.wav 

\ -c:a copy 

\ -f rtp \ "rtp://127.0.0.1:11111"

RTSP работает как remote control. Например: Воспроизведение, пауза и т. д. — вот что реализует и позволяет контролировать RTSP.

А кто передает данные? RTP — это транспортный протокол, используемый RTSP (RTP использует UDP).

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

Например, если есть потеря пакета на стороне получателя при передаче пакета (кадра) h.264, он может запросить у отправителя полный i‑й кадр.

RTCP — это просто протокол управления, который работает с RTP для QoS Metric (его основная цель — сбор статистики для сеанса RTP).

Сейчас все в браузерах. Можем ли мы транслировать мультимедиа в браузер? Да, именно здесь на сцену выходит WebRTC. WebRTC снова использует протокол RTP.

WebRTC — это стандарт, который помогает выполнять потоковую передачу мультимедиа из/в браузеры. Кроме того, он имеет дополнительные функции.

В случае рассматриваемого примера (сервис видео‑аудио‑связи с постобработкой), клиентское приложение может выглядеть следующим образом:

Источник данных — видео с камеры и с микрофона клиентского устройства. Поток с камеры можно получать в виде RTSP потока и в дальнейшем отправлять на бекенд системы в исходном виде, либо в формате пользовательских библиотек (например, openCV), а также WebRTC и затем отправлять на бекенд.

Несмотря на то, что WebRTC является peer‑to‑peer технологией, вам все равно придется управлять веб‑серверами и платить за них. Чтобы два одноранговых узла могли общаться друг с другом, вам необходимо использовать сигнальный сервер для настройки, управления и завершения сеанса связи WebRTC. В сценариях вещания WebRTC «один ко многим» вам, вероятно, понадобится медиа‑сервер WebRTC, который будет выступать в качестве промежуточного программного обеспечения для мультимедиа. С WebRTC сложно начать. Существует множество концепций, которые вам нужно изучить и освоить: различные интерфейсы WebRTC, кодеки и обработка мультимедиа, трансляция сетевых адресов (NAT) и брандмауэры, UDP (основной базовый протокол связи, используемый WebRTC) и многое другое.

Поэтому для примера выберем клиентскую библиотеку OpenCV и передачу данных потока через вебсокеты.

Сервис сбора данных

Двигаемся дальше: узел сбора данных

Соединение типа «поток» отличается от классического «запрос‑ответ». В случае потока соединение запрашивается сервером (службой), а клиент (источник потока) предоставляет непрерывный ответ.

Как можно масштабировать сервис сбора данных?

В связи с тем, что после установления соединения один узел обрабатывает поток до его завершения, обычно добавляется так называемый «слой буферизации».

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

Также можно применять и стандартный балансировщик нагрузки (например, nginx), но он подойдет только для распределения по узлам сбора данных разных потоков. В рамках одного потока стандартный балансировщик нагрузки бесполезен.

Существует несколько точек отказа у сервиса сбора данных. Они представлены на рисунке ниже:

Таким образом, потенциальные точки потери данных, при отказе узла — это:

  • когда данные от источника не доставлены в сервис сбора данных (из‑за проблем сети)

  • когда данные были получены сервисом сбора данных, но не переданы на обработку в следующие сервисы системы.

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

1. Контрольные точки (глобальный снимок всей системы). Например: Word, Google Docs, VMs, WIndows (не подходит для потоковых систем!)

2. Логирование действий (событий). Например: паттерн event‑sourcing в MSA

В случае логирования действий (событий) если несколько вариантов, где в сервисе сбора данных можно осуществлять логирование:

  • Логирование сообщений на стороне получателя — RBML

  • Логирование сообщений на стороне отправителя — SBML

  • Гибридное логирование сообщений (HML)

У первых двух подходов: RBML и SBML есть очевидный недостаток: если сервис упадет до момента отправки данных в брокера сообщений или до обработки данных в узле сервиса сбора данных, то данные будут потеряны. Поэтому для большей отказоустойчивости стоит либо одновременно применять RBML и SBML, либо гибридное логирование HML. При совместном применении RBML и SBML удваивается объем хранилища данных, где нам нужно сохранять сырые данные, а HML позволяет этого избежать.

В качестве хранилища сырых данных можно использовать любое персистентное nosql‑хранилище (например, key‑value базу данных, тот же редис, либо хранилище оптимизированное под хранение больших объемов сырых данных — например, cassandra).

Возвращаясь к примеру, в сервисе видео‑звонков, в сервисе сбора данных от клиентских приложений, будем использовать websocket‑ы и rocketDB key‑value store) для хранения сырых данных потока.

Передача данных между сервисами

Для передачи потоковых данных между сервисами системы лучше всего подходит брокер сообщений kafka (или kafka streams).

Про настройку кластера kafka написано множество статей, поэтому здесь это обсуждать не будем.

Что нужно помнить:

  • Геораспределенные системы — узлы кластера kafka могут находиться в разных дата‑центрах

  • Отказоустойчивость — в кластере kafka можно настроить репликацию данных и бекапы.

  • Семантика доставки сообщений — хотим «доставку только один раз»

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

  • Если один из брокеров вышел из строя: нам поможет HML

  • Разрыв одного из сетевых соединений: использовать репликацию

  • Поломка диска: тоже поможет репликация

Сервисы обработки данных

Обработка медиа‑данных — очень тяжелая операция. Для сервисов обработки данных можно использовать специальные фреймворки, предназначенные для highload‑вычислений и потоковых данных. Это:

  • Apache Ignite

  • Apache Storm

  • Flink

В нашем примере остановимся на Apache Ignite. Это фреймворк, который подходит для нагруженных распределенных вычислений.

Работа с потоковыми данными из брокеров сообщений происходит с помощью так называемых Streamer‑ов. Примерная схема обработки потоковых данных в Apache Ignite показана на схеме ниже:

В целом все трансформации данных (например, распознавание лица), это не real‑time действия, поэтому при получении данных через DataStreamer мы кладем часть потока мультимедиа‑данных в кэш и накапливаем некоторый объем данных, нужный для корректной работы Transformer‑ов. Transformer‑ы берут данные из кэша, выполняют их обработку и передает в ProcessorService, который сохраняет аналитические данные в БД и возвращает клиенту обработанный и преобразованный поток медиа‑данных.

Transformer‑ы, Service‑ы и кэши распределены по всему кластеру Apache Ignite в соответствии с data affinity (подробнее про data partitioning можно прочитать по ссылке: https://ignite.apache.org/docs/latest/data‑modeling/data‑partitioning#partitionedreplicated‑mode).

Более подробно как работают сервисы преобразования видео‑потока звонков для примера показано на диаграмме ниже:

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

В завершение приглашаю всех на бесплатный урок, где мы рассмотрим преимущества и недостатки синхронного и асинхронного взаимодействия, обсудим паттерн message bus, познакомимся с CQRS, оркестрацией и хореографией.

Что еще почитать по теме:
  • Статья: A Survey of Rollback-Recovery Protocols in Message-Passing Systems (1996) by E. N. ( Mootaz) Elnozahy , Lorenzo Alvisi , Yi-min Wang , David B. Johnson

  • Грегор Хоп, Бобби Вульф: Шаблоны интеграции корпоративных приложений (книга на русском с комментариями на github).

  • Robert Daigneau: Service Design Patterns: Fundamental Design Solutions for SOAP WSDL and RESTful Web Services

  • Статья: Hybrid Message Logging. Combining advantages of Sender-based and Receiver-based approaches (2014) by Hugo Meyer, Dolores Rexachs, and Emilio Luque

  • https://dzone.com/articles/running-microservices-on-top-of-in-memory-data-grid 

  • https://ignite.apache.org/docs/latest/services/services 

Комментарии (2)


  1. web3_Venture
    00.00.0000 00:00

    Столько вопросов , почему Ignite , почему ни spark , ни ksql , ни другие? Почему вы копите батчи хотя везде говорите о стримингах, Ignite не поддерживает оконные функции?


  1. talgin
    00.00.0000 00:00

    А где вы делите видео на кадры? И как с помощью kafka вы пересылаете кадры? Не возникает ли лаг при чтении/записи с/на kafka?