Создаем сигнальную среду для резервирования транскодеров по схеме N+k

Все чаще бизнесу приходится резервировать текущую инфраструктуру, чтобы повысить свою отказоустойчивость и качество предоставляемых услуг. Как правило, резервируется целая машина с нужным сервисом или кластер по схеме N+N. Но, что, если серверов много, а данные, которые нужны для полного восстановления сервиса, весят меньше мегабайта? 

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

Если вы решите создать свою сигнальную среду, эта статья для вас. 

Предметная область

Сейчас я работаю на проекте, который специализируется на транскодировании и потоковой передаче видео в реальном времени. Движок поставляется в виде серверного ПО по лицензии. Имеет поддержку популярных протоколов передачи видео данных и большой набор различных решений для бизнеса — шифрование видеопотоков, наложение логотипов, blackout (перекрытие эфира), поддержку меток (SCTE, DTMF). К основной части ПО отдельно поставляется UI. Это весомый плюс, который сыграет в последствии нам на руку.  

Известно, что ПО приобретают как единичными экземплярами, так и разворачивают на целые кластеры. Те, кому позволяют возможности и инфляция приобретают сразу дублирующие лицензии и заводят зеркальные серверы (схема резервирования N+N). Другие, скорее, отказываются полностью от резервирования. И таких преимущественно больше…

Учитывая стабильность работы кодирующего ПО, статистику выхода из кластера (недоступности) машин и данные, которые нужны для восстановления (а их действительно меньше 1 МБ), мы с командой решили подготовить сервис, позволяющий применять клиентам схему резервирования N+k. 

Рецепт транскодирования

Собственно рецепт транскодирования в реальном времени сводится к четырем основным компонентам:

  • где кодировать (сервер),

  • что кодировать (источник сигнала). Чаще всего: UDP, MPEGTS-over-IP, SRT, RTMP,

  • по каким правилам (конфигурационный файл),

  • что получить на выходе (результирующий поток(и)). Чаще всего HLS, DASH, SRT, RTMP, UDP, MPEGTS-over-IP. 

Тогда для восстановления системы потребуются:

  • источник сигнала,

  • конфигурационный файл,

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

  • и, собственно, «‎живой» сервер с работающим ПО.

Кодирующее ПО включает 3 части: 

  • streambuilder — главная часть, транскодирует потоки,

  • streambuilder-api — программный интерфейс, позволяющий управлять транскодером по сети, всегда ставится с основной частью.

  • streambuilder-ui —  визуальная часть проекта или интерфейс управления пользователя. Позволяет удобно создавать конфигурации, просматривать статус сервисов и т.д. Идет как дополнительная часть, нужно устанавливать отдельно. 

UI необязательно ставить вместе с основной частью, можно использовать вообще любую машину, имеющую сетевой доступ к серверам с API. Это дало ключевой вектор в решении текущей задачи. Именно к UI мы и решили добавить логику проверки серверов на доступность, сохранение бекапов конфигураций и перенос сервисов с одного хоста на другой.

Создаем логику бекапа сервисов

По практике проекта есть два типа пользователей — рядовые и ‎продвинутые. Последние нередко управляют сервисами транскодирования напрямую через рутовую консоль в обход web-панели администратора. 

Отсюда возникает вопрос: как синхронизировать такие конфигурации? 

Решением стало создать периодическую задачу сравнения конфигураций. Как это работает: при создании конфигурации сервиса (канала/сhannel) мы добавляем его в базу данных. После чего, раз во время t_{backup}запрашиваем у хоста сравнение конфигураций.

Постоянная передача конфигураций по сети не является оптимальным решением. Вместо этого мы будем отправлять хосту название сервиса и хеш конфигурации. Если проверка проходит успешно, API возвращает «‎True». В случае несоответствия хешей, API возвращает отрицательный ответ, а также конфигурацию и её хеш, которые мы сохраняем в базе данных. Это позволяет быстро перенести конфигурацию на резервный хост и запустить сервис там, если основной хост становится недоступным.

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

Настраиваем проверки доступности серверов 

На текущем этапе мы остановились на проверках двух типов: доступность API и доступность хоста. 

Основной и первой работает проверка доступности API раз в t_{main} сек. Если проверка не проходит, хосту назначается статус «‎обрати внимание». Здесь же запускается дополнительная вторая проверка, которая срабатывает мультикаст, если мы используем UDP. С выходом в UDP проблем тоже нет, отправляем вещать выход в мультикаст.

При использовании выходов с манифестами HLS или DASH всё немного сложнее — нужен DNS сервер. DNS должен иметь конечную точку, которая даёт возможность быстро изменить адрес сервера для конкретного имени, при смене сервера на котором работает сервис. Логика такая: клиент получает ссылку на плейлист (test_channel_host.com/live.m3u8), которая ведёт к серверу, где изначально находится сервис. При смене расположения канала система резервирования сигнализирует DNS серверу о том, что теперь выход с канала нужно забирать с другого сервера. Приняв запрос, DNS меняет записи в таблице на новые (например test_channel_host.com = 192.168.100.20 меняется на 192.168.100.52), что позволяет клиенту не менять адрес источника при смене сервера. Этот функционал сейчас находится в разработке.

Файлы, которые используются при кодировании потоков

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

Для таких файлов предлагается использовать сетевое хранилище — сервис при запуске загружает нужные ему файлы по ссылкам указанным в конфигурации, что играет нам на руку и избавляет от необходимости:

  • перебрасывать медиа файлы по сети между хостами,

  • обновлять пути хранения файлов в конфигурациях.

Тесты и выводы

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

Максимальное время вычисляется как t_{main}+(t_{add.}*n) +t_{moving}+t_{run\ service}, где

t_{main}период основной проверки, по умолчанию 5 секунд, t _{add}*n — количество доп. проверок, умноженное на время задержки между попытками, по умолчанию 5 секунд и 5 проверок,

t_{moving}время на перенос каналов. Зависит от производительности хоста и сети, в среднем 10 сервисов в секунду, здесь считаем 10 сервисов.

t_{run\ service}— среднее время запуска сервиса, зависит от того, когда придёт ключевой кадр.

Получается 5+25+1+10 = 31 секунда, если использовать стандартные настройки, но это время можно уменьшить изменив настройки под конкретную сеть.

Минимально рекомендованные:  t_{main}=2 , t_{add.},n=3позволяют сократить время до максимум 19 секунд. 

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

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


ссылка на оригинал статьи https://habr.com/ru/articles/752486/

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *