Добрый день Я недавно прочитал очень интересная статья про обработку 50 гигабит/с на сервере и вспомнил, что у меня в черновиках была статья о том, как год назад мы разработали систему мониторинга видеопотоков с общим объемом трафика до 100 Гбит/с.
Еще раз «прочитал» и решил представить разработчикам.
Статья больше посвящена анализу протоколов и поиску архитектурного решения, а не настройке различных подсистем Linux, потому мы пошли по пути распределения нагрузки между сервером и сетевыми зондами, подключающимися к транспортным потокам 10 Gigabit Ethernet.
Если вас интересует, как нам удалось измерить характеристики сетевых потоков с 55 тысяч видеокамер, обращайтесь под кат.
В этой статье я планирую рассказать о:
- что такое объект мониторинга, как к нему подключиться;
- параметры видеопотоков, которые необходимо измерить;
- нюансы.
это понятно: в каждой задаче есть нюансы;
- муки выбора подходящей архитектуры;
- Протокол RTP и его свойства, позволяющие получателю анализировать качество потока;
- идентификация пакетов RTP в магистральном трафике;
- окончательная архитектура системы;
- преимущества и недостатки выбранного решения.
Что мы отслеживаем?
Вам необходимо контролировать несколько транспортных Ethernet-каналов 10G, по которым передаются десятки тысяч видеопотоков.Первая установка – 22 тысячи камер, вторая – 55 тысяч.
Средний битрейт камеры составляет 1 Мегабит/с.
Есть камеры с 2 мегабит/с и 500 килобит/с.
Видео передается по протоколам RTP-over-UDP и RTP-over-RTSP-over-TCP, а соединения устанавливаются по RTSP. При этом один поток может идти с одного IP-адреса (один адрес — одна камера), либо с нескольких (один адрес — один энкодер, то есть от 1 до 16 потоков).
Подключение к Ethernet-каналам возможно только в режиме мониторинга с использованием оптических соединителей, то есть в неинтрузивном режиме.
Такое подключение является предпочтительным, так как в этом случае трафик не проходит через оборудование и, следовательно, никак не может повлиять на качество предоставляемых услуг (падение уровня оптического сигнала на разветвителе мы считаем совсем незначительно).
Это чрезвычайно важный аргумент для операторов.
А для разработчиков такое подключение влечет за собой важный нюанс — наблюдать за потоками всегда придется «со стороны», поскольку пакеты не могут передаваться в сеть (например, нельзя отправить пинг и получить ответ).
Это значит, что вам придется работать в условиях недостатка информации.
Что мы измеряем?
Оценка качества потока основана на анализе заголовков транспортного протокола RTP и заголовков NAL-блоков h.264. Качество изображения не измеряется.Вместо этого транспортный поток видеокадров анализируется по следующим критериям:
- пакеты не теряются;
- пакеты не меняют свой порядок;
- количество кадров соответствует SLA;
- битрейт соответствует SLA;
- джиттер пакетов в норме;
- и, наконец, что камера вообще передает пакеты.
Да-да, несмотря на то, что в RTSP RFC написано, что режим Interleaving Data лучше не использовать — см.
Итого: система мониторинга представляет собой комплекс, подключенный в неинтрузивном режиме к n-ному числу 10-гигабитных Ethernet-каналов, который непрерывно «отслеживает» передачу всех RTP-видеопотоков, присутствующих в трафике, и проводит измерения в определенное время.
интервал, чтобы сохранить их позже в базе данных.
На основе данных из базы данных регулярно формируются отчеты по всем камерам.
Что в этом такого сложного?
В процессе поиска решения сразу выявилось несколько проблем:- Ненавязчивое соединение.
Система мониторинга подключается к уже работающим каналам, в которых уже установлено большинство соединений (по RTSP), сервер и клиент уже знают, какими портами происходит обмен, но мы не знаем этого заранее.
Хорошо известный порт предназначен только для протокола RTSP, но UDP-потоки могут проходить через произвольные порты (кроме того, оказалось, что они часто нарушают требование СЛЕДУЕТ соблюдать четность/нечетность портов, см.
rfc3550 ).
Как определить, что конкретный пакет с определенного IP-адреса принадлежит видеопотоку? Например, протокол BitTorrent ведет себя аналогичным образом — на этапе установления соединения клиент и сервер согласовывают порты, и тогда весь UDP-трафик выглядит как «просто битовый поток».
- Связанные ссылки могут содержать не только видеопотоки.
Это могут быть HTTP, BitTorrent, SSH и любые другие протоколы, которые мы используем сегодня.
Поэтому система должна правильно идентифицировать видеопотоки, чтобы отделить их от остального трафика.
Как это сделать в реальном времени с 8-ю десятигигабитными каналами? Конечно, они обычно заполнены не на 100%, поэтому общий трафик будет не 80 гигабит/с, а около 50-60, но это не так уж и мало.
- Масштабируемость.
Там, где видеопотоков уже много, их может быть еще больше, поскольку видеонаблюдение уже давно зарекомендовало себя как эффективный инструмент. Это говорит о том, что должен быть резерв по производительности и резерв по ссылкам.
Ищем подходящее решение.
Мы, естественно, стремились максимально использовать собственный опыт. К моменту принятия решения у нас уже была реализация обработки Ethernet-пакетов на устройстве на базе FPGA. Беркут-MX (проще – МХ).
С помощью Беркута-MX нам удалось получить необходимые поля для анализа из заголовков Ethernet-пакетов.
К сожалению, у нас не было опыта обработки такого объёма трафика с помощью «обычных» серверов, поэтому к такому решению мы относились с некоторой осторожностью.
Казалось бы, достаточно было просто применить метод к RTP-пакетам и золотой ключик был бы у нас в кармане, но MX умеет только обрабатывать трафик, возможностей учета и хранения статистики у него нет. Памяти в ПЛИС не хватает для хранения найденных соединений (комбинаций IP-IP-порт-порт), потому что в 2х10-гигабитном канале, входящем на вход, может быть около 15 тысяч видеопотоков, и для каждого нужно « запомнить» количество полученных пакетов, количество потерянных пакетов и так далее.
Более того, поиск на такой скорости и такого количества данных при условии обработки без потерь становится нетривиальной задачей.
Чтобы найти решение, нам пришлось «копнуть глубже» и выяснить, какие алгоритмы мы будем использовать для измерения качества и идентификации видеопотоков.
Что можно измерить с помощью полей пакета RTP?
Формат пакета RTP описан в rfc3550 .
Из описания понятно, что с точки зрения измерений качества в RTP-пакете нас интересуют следующие поля:
- порядковый номер — 16-битный счетчик, который увеличивается с каждым отправленным пакетом;
- timestamp — временная метка, для h.264 значение дискретизации составляет 1/90000 с (т.е.
соответствует частоте 90 КГц);
- Маркерный бит. В rfc3550 вообще описано, что этот бит предназначен для обозначения «значительных» событий , но на самом деле камеры чаще всего используют этот бит для обозначения начала видеокадра и специализированных пакетов с информацией SPS/PPS.
- потеря кадров;
- повторно отправить пакет (дублировать);
- изменение порядка поступления (перезаказ);
- перезагрузка камеры, если в последовательности имеется большой «пробел».
- изменение задержки (также называемое джиттером).
В этом случае на приемной стороне должен работать счетчик 90 кГц;
- в принципе задержка прохождения пакета.
Но для этого необходимо синхронизировать время камеры с меткой времени, а это возможно, если камера передает отчеты отправителя (RTCP SR), что в целом неверно, поскольку в реальной жизни многие камеры игнорируют сообщение RTCP SR (о половина камер, с которыми мы работали).
Правда, кадры SPS/PPS протокола h.264 вносят ошибку, т.к.
не являются видеокадрами.
Но это можно смягчить, используя информацию из заголовка NAL-блока, который всегда следует за заголовком RTP. Подробные алгоритмы измерения параметров выходят за рамки статьи; Я не буду углубляться.
Если вам интересно, в rfc3550 есть пример кода.
расчет потерь И формулы расчета джиттера .
Основной вывод заключается в том, что для измерения основных характеристик транспортного потока достаточно всего нескольких полей из пакетов RTP и блоков NAL. А вот остальная информация в измерениях не участвует и ее можно и нужно отбросить!
Как идентифицировать потоки RTP?
Для ведения статистики информация, полученная из заголовка RTP, должна быть «привязана» к некоторому идентификатору камеры (видеопотока).Камеру можно однозначно идентифицировать по следующим параметрам:
- IP-адреса источника и назначения
- Порты источника и назначения
- ССРК.
Особое значение это имеет, когда с одного IP транслируется несколько потоков, т.е.
в случае многопортового кодера.
Видимо это связано с экономией ресурсов.
В результате нам пришлось добавить порты в идентификатор камеры.
Это полностью решило проблему уникальности.
Как отделить пакеты RTP от остального трафика?
Остается вопрос: как Беркут-MX, получив пакет, поймет, что это RTP? Заголовок RTP не имеет такой явной идентификации, как IP, не имеет контрольной суммы, может передаваться по UDP с номерами портов, которые выбираются динамически при установлении соединения.Но в нашем случае большая часть соединений уже давно установлена и ждать переустановки можно очень долго.
Чтобы решить эту проблему в rfc3550 (Приложение А.
1) Рекомендуется проверить биты версии RTP — это два бита, а поле Payload Type (PT) — семь бит, что в случае динамического типа принимает небольшой диапазон.
На практике мы выяснили, что для многих камер, с которыми мы работаем, ПТ попадает в диапазон от 96 до 100. Есть еще один фактор – паритет портов, но как показала практика, он не всегда соблюдается, поэтому от него пришлось отказаться.
Таким образом, поведение Беркута-MX следующее:
- Получаем пакет, разбираем его на поля;
- если версия 2 и тип полезной нагрузки находится в заданных пределах, то мы отправляем заголовки на сервер.
под такие простые критерии могут попасть не только RTP-пакеты.
Но нам важно, что мы точно не пропустим RTP-пакет, и сервер отфильтрует «неправильные» пакеты.
Для фильтрации ложных случаев сервер использует механизм, регистрирующий источник видеотрафика в нескольких последовательно полученных пакетах (пакет содержит порядковый номер!).
Если пришло несколько пакетов с последовательными номерами, то это не случайное совпадение и мы начинаем работать с этим потоком.
Этот алгоритм оказался очень надежным.
Давайте двигаться дальше.
Поняв, что вся поступающая в пакетах информация не нужна для измерения качества и идентификации потоков, мы решили всю высоконагруженную и критическую по времени работу по приему и изоляции полей RTP-пакетов возложить на Беркут-МХ, то есть на ПЛИС.
Он «находит» видеопоток, парсит пакет, оставляет только необходимые поля и отправляет его по UDP-туннелю на обычный сервер.
Сервер проводит измерения для каждой камеры и сохраняет результаты в базу данных.
В результате сервер работает не с 50-60 Гигабит/с, а максимум с 5% (именно это соотношение отправляемых данных к среднему размеру пакета).
То есть вход всей системы — 55 Гигабит/с, а до сервера доходит только не более 3 Гигабит/с!
В итоге у нас получилась следующая архитектура:
И первый результат в этой конфигурации мы получили через две недели после задания первоначального технического задания!
Что в итоге делает сервер?
Так что же делает сервер в нашей архитектуре? Его задачи:- прослушивать UDP-сокет и читать из него поля с упакованными заголовками;
- анализировать входящие пакеты и извлекать поля заголовка RTP вместе с идентификаторами камер;
- соотнести полученные поля с полученными ранее и понять, были ли потеряны пакеты, отправлялись ли пакеты повторно, изменился ли порядок прибытия, каков был разброс задержки пакетов (джиттер) и т. д.;
- записать измеренные данные в базу данных с привязкой ко времени;
- анализировать базу данных и формировать отчеты, отправлять оповещения о критических событиях (высокая потеря пакетов, потеря пакетов с какой-либо камеры и т. д.).
Более того, можно будет подключать новые линки и MX, ведь запас производительности сохраняется.
Вот так выглядит верх сервера (это верх только одного lxc-контейнера, отчеты формируются в другом):
Он показывает, что вся нагрузка по расчету параметров качества и учету статистики распределяется равномерно по четырем процессам.
Добиться такого распределения нам удалось с помощью хеширования в FPGA: по IP вычисляется хеш-функция, а младшие биты полученного хеша определяют номер UDP-порта, на который пойдет статистика.
Соответственно, каждый процесс, прослушивающий свой порт, получает примерно одинаковое количество трафика.
За и против
Пришло время похвастаться и признать недостатки решения.Начну с плюсов:
- отсутствие потерь на интерфейсе со ссылками 10G. Поскольку все «воздействие» берет на себя FPGA, мы можем быть уверены, что каждый пакет будет проанализирован;
- для мониторинга 55 000 камер (или более) вам понадобится только один сервер с одной картой 10G. Сейчас мы используем сервера на базе двух Xeon с четырьмя ядрами по 2400 МГц каждое.
Достаточно сэкономить: параллельно со сбором информации формируются отчеты;
- мониторинг 8 «десяток» (каналы 10G) умещается всего в 2-3 блока: не всегда есть много места и мощности в стойке для системы мониторинга;
- при подключении линков от МХ через свитч можно добавлять новые линки не прекращая мониторинг, ведь в сервер не нужно вставлять никакие платы и не нужно его для этого отключать;
- сервер не перегружен данными, он получает только то, что необходимо;
- заголовки от MX приходят в гигантском Ethernet-пакете, а значит процессор не будет перегружен прерываниями (кроме того, не забываем про объединение прерываний).
- из-за жесткой оптимизации под конкретную задачу добавление поддержки новых полей или протоколов требует внесения изменений в код FPGA. Это приводит к большим затратам времени, чем если бы мы проделали то же самое на процессоре.
Как при разработке и тестировании, так и при развертывании;
- видеоинформация вообще не анализируется.
Возможно, камера снимает висящую перед ней сосульку или она может быть направлена не в ту сторону.
Этот факт останется незамеченным.
Мы, конечно, предусмотрели возможность записи видео с выбранной камеры, но обойти все 55 000 камер оператор не может!
- сервер и устройства на базе FPGA стоят дороже, чем один или два сервера;)
Краткое содержание
В итоге у нас получился программно-аппаратный комплекс, в котором мы можем контролировать как ту часть, которая парсит пакеты на интерфейсах, так и ту часть, которая ведет статистику.Полный контроль над всеми узлами системы буквально спас нас, когда камеры начали переключаться в чередующийся режим RTSP/TCP. Потому что в этом случае заголовок RTP уже не располагается в пакете по фиксированному смещению: он может располагаться где угодно, даже на границе двух пакетов (первая половина в одном, вторая в другом).
Соответственно, кардинальным изменениям подвергся алгоритм получения RTP-заголовка и его полей.
Пришлось делать пересборку TCP на сервере для всех 50 000 подключений — отсюда и довольно высокая нагрузка в топе.
Мы никогда раньше не работали в области высоконагруженных приложений, но нам удалось решить проблему, используя наши навыки работы с FPGA, и получилось довольно неплохо.
Остался даже резерв — например, к системе с 55 000 камер можно подключить еще 20–30 тысяч потоков.
Настройку подсистем Linux (распределение очередей прерываний, увеличение буферов приема, прямое выделение ядер конкретным процессам и т.д.) я оставил за рамками статьи, т.к.
эта тема уже очень хорошо освещена.
Я не все описал, граблей набралось много, так что не стесняйтесь задавать вопросы :)
Огромное спасибо всем, кто дочитал до конца!
Ссылки
- Брошюра по системе мониторинга Беркут-MX/RTP
- Наверное, самой популярной компанией, занимающейся подобными задачами, является Бриджтек
- Карты сетевых ускорителей в ПК для обработки трафика - напатех .
Один из методов — классификация кадров — аналогичен подходу, который мы использовали.
Однако он не справится с эвристическим поиском заголовка RTP в любом месте TCP-пакета.
- rfc3550 - RTP описан здесь
- rfc2326 - RTSP описан здесь
- Мега-статья про обработку 50 гигабит на сервере
-
Веб-Хостинг: Вывод Веб-Сайта На Первое Место
19 Oct, 24 -
Когда Утка Не Крякает
19 Oct, 24 -
Как Правильно Подготовить Блокчейн
19 Oct, 24 -
Каталог Интернет-Магазинов Беларуси
19 Oct, 24