Требования и подбор оборудования
Что нужно от операционной системы и железа и как посчитать процессор, память, диски и сеть под N потоков и M зрителей.
Сервер — один исполняемый файл без внешних зависимостей: ни базы данных, ни брокера сообщений, ни отдельного веб-сервера ставить не нужно. Требования сводятся к версии ядра Linux, разрядности процессора и здравому расчёту ресурсов под нагрузку.
Коротко#
| Что | Минимум | Рекомендуется |
|---|---|---|
| Архитектура | x86-64 | x86-64 |
| Ядро Linux | 5.1 (io_uring) | 5.15 и новее |
| Библиотека C (glibc) | 2.31 | 2.31 и новее |
| Инициализация | systemd | systemd |
| Права запуска | root | root |
| Процессор | 2 ядра | по расчёту ниже + запас ×2 |
| Память | 1 ГБ | по расчёту ниже + запас ×2 |
| Диск под программу | 100 МБ | 1 ГБ (журналы, состояние TLS) |
| Диск под архив | не нужен, если архив не ведётся | отдельный том, см. Диски под архив |
Проверить хост до установки:
uname -m # ожидается: x86_64 uname -r # ожидается: 5.1 или новее ldd --version | head -1 # ожидается: 2.31 или новее systemctl --version | head -1 # systemd должен присутствовать nproc # число логических ядер free -g # объём памяти
Операционная система#
Требуется Linux x86-64 с ядром 5.1 и новее и glibc 2.31 и новее. Исполняемый файл собран
с нижней границей glibc 2.31 и работает на любом дистрибутиве, где эта граница выдержана; чаще всего
установке мешают именно устаревшее ядро или устаревшая glibc. Дополнительно нужны systemd и openssl
— установщик проверяет всё перечисленное и отказывается работать с точным указанием причины.
Служба запускается от root. Это не прихоть: под root сервер применяет сетевые настройки ядра и
режим процессора при старте (иначе он только печатает рекомендации), а модуль лицензирования читает
аппаратные идентификаторы, часть которых доступна только root. Ограничения ресурсов задаются не
пользователем, а cgroup-параметрами в systemd-юните (MemoryMax, CPUQuota) — см.
Установка с нуля.
Некоторые сборки ядра и политики безопасности отключают io_uring целиком. Проверьте:
sysctl kernel.io_uring_disabled — значение должно быть 0. Если такого параметра в системе нет,
это нормально: в вашем ядре io_uring отключать нечем. Установочный набор кладёт
/etc/sysctl.d/99-hastreamer.conf, где параметр выставлен явно.
Что даёт io_uring#
Весь ввод-вывод — сеть, таймеры, файлы архива — идёт через io_uring: механизм ядра, в котором операции ставятся в очередь пакетами и завершения забираются пакетами, без системного вызова на каждый пакет. На нагрузке в тысячи соединений это основной источник экономии процессора и причина, по которой ядро 5.1 указано как жёсткий минимум, а не как пожелание.
Вторая половина экономии — модель «ничего общего»: каждое ядро процессора владеет своими соединениями и своими потоками. Отсюда практическое следствие для подбора железа: важно число ядер, а не частота одного, и не имеет смысла оставлять серверу одно ядро (см. Архитектура).
Как считать ресурсы#
Порядок приоритетов при подборе: процессор важнее памяти, память важнее сети. Считайте в этом же порядке, но проверьте все три — сеть чаще всего становится физическим потолком раньше, чем процессор.
Главное правило, которое связывает все три величины: стоимость потока пропорциональна его битрейту. Сервер не перекодирует видео, он перекладывает байты; вдвое более «тяжёлая» камера стоит вдвое дороже по процессору, памяти и сети. Ни разрешение, ни кодек сами по себе в расчёт не входят — только мегабиты в секунду.
Опорные измерения#
Числа ниже измерены на восьмиядерном сервере x86-64 на реальных камерах и синтетических источниках. Приведены два битрейта, чтобы был виден масштаб пересчёта.
Приём (ingest) — стоимость 1000 одновременно принимаемых потоков:
| Битрейт источника | Ядер на 1000 потоков | Память на поток |
|---|---|---|
| ~1,1 Мбит/с (типовая камера видеонаблюдения) | 0,6 – 0,7 | ~5 МБ |
| ~1,2 Мбит/с | ~1,0 | ~7 МБ |
| ~5,5 Мбит/с | 2,2 – 3,0 | ~16 МБ |
Стоимость приёма линейна по числу потоков: тысячный поток стоит столько же, сколько первый. Приём по HLS немного дешевле приёма по RTSP (целые сегменты вместо отдельных RTP-пакетов), но добавляет задержку в один-два сегмента.
Раздача (egress) — стоимость 1000 одновременных зрителей одного потока:
| Протокол | При ~1,1 Мбит/с | При ~5,5 Мбит/с |
|---|---|---|
| HLS-fMP4 | 0,04 ядра | 0,14 ядра |
| MSE-WS | 0,09 ядра | 0,45 ядра |
| RTSP поверх TCP | не измерялось | 1,05 ядра |
В измерениях не участвовала реальная сетевая карта, поэтому в расчёт закладывайте запас на драйвер и прерывания NIC — тем больший, чем ближе исходящий трафик к пропускной способности порта.
Память. Кольцевой буфер потока рассчитан по времени, а не по числу байт, поэтому память на поток тоже пропорциональна битрейту: ~5 МБ при 1 Мбит/с, ~16 МБ при 5,5 Мбит/с. Плюс постоянная часть процесса — порядка 100–150 МБ. Число зрителей на память практически не влияет: зритель получает ссылку на уже готовый фрагмент, а не его копию.
Порядок расчёта#
- Процессор.
ядра_приёма = потоки / 1000 × 0,6 × (битрейт / 1,1)плюсядра_раздачи = зрители / 1000 × 0,04 × (битрейт / 1,1)для HLS (для MSE-WS — коэффициент 0,09). - Память.
потоки × 5 МБ × (битрейт / 1,1)плюс 150 МБ на процесс. - Сеть. Входящий трафик = сумма битрейтов источников. Исходящий = битрейт × число зрителей.
- Умножьте процессор и память на 2. Запас нужен на пики переподключений, обслуживание архива, всплески при перезапуске камер и на саму операционную систему.
Пример расчёта#
Задача: 500 камер по 4 Мбит/с, до 2000 одновременных зрителей по HLS, архива нет.
| Величина | Расчёт | Итог |
|---|---|---|
| Ядра на приём | 500/1000 × 0,6 × (4/1,1) | ≈ 1,1 ядра |
| Ядра на раздачу | 2000/1000 × 0,04 × (4/1,1) | ≈ 0,3 ядра |
| Память | 500 × 5 МБ × (4/1,1) + 150 МБ | ≈ 9,3 ГБ |
| Входящий трафик | 500 × 4 Мбит/с | 2 Гбит/с |
| Исходящий трафик | 2000 × 4 Мбит/с | 8 Гбит/с |
С запасом ×2 получается сервер на 4–6 ядер и 16–24 ГБ памяти. Обратите внимание: по процессору задача почти ничего не стоит, а ограничением становится сеть — 8 Гбит/с исходящего трафика требуют 10-гигабитного порта и соответствующего аплинка. Это типичная картина для раздачи: считайте сеть первой, даже если приоритет оптимизации у процессора.
corescores 1 не «уменьшает нагрузку», а сводит всю работу на одно ядро: оно будет занято на 100 %, пока
остальные простаивают. Значение по умолчанию 0 («все производительные ядра хоста») подходит почти
всегда. Если нужно поделить сервер с другими службами, ограничивайте его через systemd
(CPUQuota=), а не через cores.
Диски под архив#
Архив (DVR) пишется непрерывно и последовательно: один открытый файл на записываемый поток, ротация по времени сегмента. Требования к диску скромные по IOPS, но серьёзные по объёму.
Объём. Один мегабит в секунду записи — это примерно 10,8 ГБ в сутки. Формула:
объём (ГБ) = битрейт (Мбит/с) × 10,8 × глубина (суток) × число потоков
| Сценарий | Расчёт | Объём |
|---|---|---|
| 100 камер × 2 Мбит/с, 7 суток | 2 × 10,8 × 7 × 100 | ≈ 15,1 ТБ |
| 500 камер × 1 Мбит/с, 30 суток | 1 × 10,8 × 30 × 500 | ≈ 162 ТБ |
| 8 камер × 4 Мбит/с, 14 суток | 4 × 10,8 × 14 × 8 | ≈ 4,8 ТБ |
Если камера пишет с переменным битрейтом, берите верхнюю границу: сцена с движением даёт заметно больше, чем статичная.
Практические требования:
- Отдельный том под архив. Не размещайте архив на системном разделе: заполненный корень останавливает не только запись, но и журналы, и саму службу.
- Порог вытеснения. У хранилища есть предохранитель
evict_at_percent(по умолчанию 90 %): при превышении заполнения удаляются самые старые записи по всем потокам. Он не заменяет расчёт глубины, а страхует от переполнения. - Файловая система — любая обычная журналируемая. Сетевые ФС и тома с высокой задержкой нежелательны: медленный диск не тормозит приём (буфер не подпирается), но приводит к разрывам в записи.
- Холодный уровень. Долгую глубину дешевле держать в S3-совместимом хранилище, оставив на диске «горячие» часы. См. Хранилища и S3.
В строке dvr m — это минуты, а месяцы — это mo. dvr local 30m хранит тридцать минут, а
не тридцать месяцев. Единицы объёма — двоичные и только в верхнем регистре: 40G, а не 40g.
Сеть#
| Что учесть | Как считать |
|---|---|
| Входящая полоса | сумма битрейтов всех источников; для запаса — ×1,3 на всплески |
| Исходящая полоса | битрейт × число одновременных зрителей (главный потребитель) |
| Задержка до камер | значения выше 100 мс требуют увеличить таймауты приёма |
| Многоадресный приём | требуется настроенный IGMP на коммутаторе и маршрут до группы |
| Раздача по RTSP поверх UDP | каждому зрителю нужна пара UDP-портов; тысячи зрителей исчерпывают диапазон эфемерных портов по умолчанию |
Диапазон эфемерных портов и размеры сетевых буферов расширяет установочный файл
/etc/sysctl.d/99-hastreamer.conf. Без него сервер работает, но упирается в ограничения ядра
раньше, чем в собственные.
Порты, которые нужно открыть в межсетевом экране:
| Порт по умолчанию | Протокол | Для чего |
|---|---|---|
8080/tcp |
HTTP | панель, API, HLS/DASH/MSE-WS, плеер |
8554/tcp |
RTSP | раздача и приём по RTSP |
40000/udp |
WebRTC | медиа-порт WHEP и WHIP |
443/tcp |
HTTPS | если включён TLS |
80/tcp |
HTTP | нужен для выпуска сертификатов ACME |
Полный список и правила смены — Порты и сеть.
Виртуальные машины и контейнеры#
Сервер работает в виртуальной машине и в контейнере при двух условиях: доступен io_uring и достаточно выделенных ядер. Дополнительно учтите:
- Ядра должны быть закреплены. «Плавающие» vCPU с переподпиской ломают модель «ничего общего»: ядро, у которого отобрали такт, задерживает свои потоки, а не соседние.
- Лицензия привязана к оборудованию. Отпечаток хоста считается по нескольким аппаратным источникам. Клонирование виртуальной машины даёт другой отпечаток, и на клоне лицензия недействительна. Подробности и допуски — Лицензирование.
- В контейнере нужны права на применение системных настроек либо предварительно настроенный хост: внутри контейнера без нужных прав сервер только напечатает рекомендации.
Что дальше#
- Установка с нуля — пошаговая установка на чистый сервер.
- Лицензирование — без действующей лицензии медиа не отдаётся.
- Производительность — как измерять нагрузку на работающей установке.