Требования и подбор оборудования
ОС и ядро, сеть, диски и расчёт ресурсов под нужное число камер.
Система состоит из двух сервисов: Plane (контрол-плейн — админка, API, база данных) и нода (сервер, который забирает видео с камер, раздаёт его зрителям и пишет архив). Требования к ним разные, и считать их надо отдельно.
Браузер получает поток напрямую с ноды; Plane никогда не проксирует медиа — он только раздаёт права и конфигурацию. Поэтому от числа камер и зрителей растёт нагрузка на ноду, а Plane остаётся почти неизменным даже на большом парке. Масштабируют систему, добавляя ноды.
Программные требования#
Общие для Plane и ноды:
| Требование | Значение | Комментарий |
|---|---|---|
| Архитектура | x86_64 |
Сборки под ARM поставляются отдельно |
| Дистрибутив | Ubuntu 20.04+, Debian 11+, RHEL/Alma/Rocky 9+ | Нужна glibc ≥ 2.31 |
| Ядро | ≥ 5.1 | Для ноды — жёсткое требование (io_uring) |
| Инициализация | systemd |
Оба сервиса — systemd-юниты |
| Пакеты | openssl |
Проверяется установщиком |
| Права | root (sudo) |
Нужны привилегированные порты (80/443) и тюнинг хоста |
Проверка на будущем сервере:
uname -m # x86_64 uname -r # 5.1 или выше ldd --version | sed -n 1p # glibc 2.31 или выше command -v systemctl openssl >/dev/null && echo "systemd + openssl OK"
Дополнительно для Plane#
- PostgreSQL — установщик поставит его сам, создаст роль
hastreamer_cctvи базуcctv. Вручную ничего создавать не нужно. Если PostgreSQL уже стоит — будет использован он. - Диск под
/var— от 20 ГБ. Там лежат база и вложения событий (снимки по движению, файлы событий). На парке с активной детекцией вложения растут быстрее базы — см. расчёт вложений. - io_uring не требуется: Plane не обрабатывает медиа.
- Ориентир для малой и средней установки: 2–4 ядра, 4–8 ГБ ОЗУ.
Дополнительно для ноды#
- io_uring обязателен — это горячий путь и сети, и файлового ввода-вывода.
- Лицензия — нода лицензируется. Без кода активации она спарится с Plane и будет видна в админке, но не примет ни одного потока. См. Лицензирование.
- Отдельный раздел под архив — не корневой, ext4 или XFS, смонтированный до установки.
# io_uring не должен быть запрещён политикой ядра sysctl kernel.io_uring_disabled # ожидается: 0 # диски под архив: отдельная точка монтирования lsblk -o NAME,SIZE,FSTYPE,MOUNTPOINT
kernel.io_uring_disabled больше нуля1 — io_uring разрешён только root-процессам, 2 — запрещён полностью. Нода работает под root,
но полагаться на это не стоит: установите kernel.io_uring_disabled=0 в /etc/sysctl.d/ и
примените sudo sysctl --system. Установщик ноды кладёт нужные параметры в
/etc/sysctl.d/99-hastreamer.conf — подробности в разделе Производительность.
Как считать ресурсы#
Считают три величины, в этом порядке — по убыванию влияния на смету:
- Диск под архив — почти всегда главная статья.
- Сеть — входящий поток с камер и исходящий к зрителям.
- CPU и ОЗУ ноды — на практике самая скромная часть.
Отправная точка для всех трёх — битрейт камеры, а не её разрешение. Нода не перекодирует видео: она перепаковывает уже сжатый поток. Поэтому 4 Мп камера, отдающая 2 Мбит/с, стоит ровно столько же, сколько 2 Мп камера с тем же битрейтом, а кодек (H.264 или H.265) на нагрузку не влияет — влияет только тот битрейт, который он выдаёт.
Битрейт своих камер посмотрите в их веб-интерфейсе (обычно «Video → Bitrate»). Типичные значения для видеонаблюдения: 1–2 Мбит/с (H.265, 1080p, 15–25 к/с) и 3–6 Мбит/с (H.264, 1080p–4 Мп, 25 к/с).
Расчёт архива#
Формула одна:
Объём архива (ГБ) = 10,8 × битрейт (Мбит/с) × число камер × глубина (суток)
Коэффициент выводится напрямую: 1 Мбит/с — это 0,125 МБ/с, за сутки 0,125 × 86 400 = 10 800 МБ, то есть 10,8 ГБ на каждый мегабит в секунду в сутки.
Пример#
120 камер, H.265 1080p по 2 Мбит/с, глубина 30 суток:
10,8 × 2 × 120 × 30 = 77 760 ГБ ≈ 77,8 ТБ + 15 % запаса (файловая система, индексы, неравномерность битрейта) ≈ 90 ТБ
Значит, нужно около 90 ТБ полезной ёмкости — например, массив из дисков по 16 ТБ с учётом RAID.
Готовая таблица#
Объём в ТБ без запаса; прибавьте к нему 10–15 %.
| Битрейт | Камер | 7 суток | 14 суток | 30 суток |
|---|---|---|---|---|
| 1 Мбит/с | 50 | 3,8 | 7,6 | 16,2 |
| 1 Мбит/с | 100 | 7,6 | 15,1 | 32,4 |
| 1 Мбит/с | 200 | 15,1 | 30,2 | 64,8 |
| 2 Мбит/с | 50 | 7,6 | 15,1 | 32,4 |
| 2 Мбит/с | 100 | 15,1 | 30,2 | 64,8 |
| 2 Мбит/с | 200 | 30,2 | 60,5 | 129,6 |
| 4 Мбит/с | 50 | 15,1 | 30,2 | 64,8 |
| 4 Мбит/с | 100 | 30,2 | 60,5 | 129,6 |
| 4 Мбит/с | 200 | 60,5 | 121,0 | 259,2 |
Что ещё влияет на объём#
| Фактор | Поправка |
|---|---|
| Звук G.711 | +64 кбит/с на камеру ≈ +0,7 ГБ в сутки |
| Запись по расписанию или по событию | Умножьте на реальную долю времени записи |
| Запись только дополнительного профиля | Считайте по битрейту этого профиля — он в разы меньше |
| Переменный битрейт (VBR) | Считайте по максимальному значению, а не по среднему |
| Копия в S3 (холодный уровень) | Объём в S3 равен объёму на диске, это не замена, а копия |
У каждого диска есть порог вытеснения (evict_at_percent, по умолчанию 90 %). При его
достижении нода удаляет самые старые записи, освобождая место под новые. Поэтому диск
всегда выглядит почти полным — это нормальная рабочая точка. Глубина архива на практике равна
той, которую позволяет ёмкость: если места меньше расчётного, записи будут вытесняться раньше
заданной глубины. Настройка — Хранилища DVR.
Сколько места занимают вложения событий#
Вложения (снимки по движению, файлы ONVIF-событий) лежат на Plane, а не на ноде. Оценка:
Объём (ГБ в сутки) = событий в сутки × размер снимка (МБ) / 1024
Снимок 1080p в JPEG — обычно 0,2–0,5 МБ. 5 000 событий в сутки по 0,3 МБ — это ~1,5 ГБ в сутки, или ~45 ГБ в месяц. Каталог вложений задаётся при установке Plane и имеет собственную политику давления по заполнению — см. plane.toml.
Расчёт сети#
Две независимые величины:
Входящий трафик ноды = сумма битрейтов всех потоков, которые она забирает Исходящий трафик ноды = битрейт потока × число одновременных зрителей этого потока
Ключевое свойство: нода забирает поток с камеры один раз и раздаёт его всем зрителям из общего буфера. Десять зрителей одной камеры не создают десять подключений к камере — входящий трафик от числа зрителей не растёт вообще.
Пример: 100 камер по 2 Мбит/с, в пике 40 одновременных зрителей.
| Направление | Расчёт | Итог |
|---|---|---|
| Входящий (камеры → нода) | 100 × 2 Мбит/с | 200 Мбит/с |
| Исходящий (нода → зрители) | 40 × 2 Мбит/с | 80 Мбит/с |
| Итого на интерфейсе | ~280 Мбит/с |
Гигабитного интерфейса такой установке достаточно с запасом. Планируйте загрузку канала не выше 50–60 % от номинала: всплески при переподключениях камер и одновременном открытии мозаики кратковременно превышают среднее значение.
Если включены оба профиля камеры (основной и дополнительный) и оба реально забираются, складывайте их битрейты. Дополнительный профиль по умолчанию работает по требованию — он занимает канал только когда его кто-то смотрит.
CPU и ОЗУ ноды — ориентир#
Приведённые цифры — отправная точка для сметы. Реальная нагрузка зависит от битрейтов, доли камер с записью, числа зрителей и качества сети до камер. Проверяйте на своём парке: поставьте пилотную ноду на 10–20 камер, снимите метрики и умножьте — метод описан ниже.
| Камер на ноде (2 Мбит/с, с записью) | Ядра | ОЗУ | Входящая сеть |
|---|---|---|---|
| до 50 | 4 | 8 ГБ | 100 Мбит/с |
| 100 | 4 | 8 ГБ | 200 Мбит/с |
| 250 | 8 | 16 ГБ | 500 Мбит/с |
| 500 | 8–16 | 16–32 ГБ | 1 Гбит/с |
| 1000 | 16 | 32–64 ГБ | 2 Гбит/с |
Оценка ОЗУ считается так (тоже ориентир):
ОЗУ (МБ) ≈ число потоков × (3 + 2,5 × битрейт в Мбит/с) + 5 МБ на каждый записываемый поток
Потребление памяти линейно зависит от битрейта, потому что буферы хранят фиксированную длительность видео, а не фиксированное число байт. Глубина архива на ОЗУ не влияет вообще: 90-суточный архив стоит столько же памяти, сколько суточный.
Юнит ноды поставляется с ограничениями MemoryHigh=6G и MemoryMax=8G. Для установки на
500+ камер этого мало — поднимите пределы через drop-in, иначе процесс упрётся в потолок
cgroup. Как это сделать — Производительность.
Как измерить на пилоте вместо гадания#
У ноды есть Prometheus-эндпоинт. Запустите 10–20 реальных камер и снимите два числа:
curl -sS http://node.example.com:8090/metrics \ | grep -E '^hastreamer_(process_cpu_cores|process_rss_bytes|streams) ' # hastreamer_process_cpu_cores 0.1840 # hastreamer_process_rss_bytes 412090368 # hastreamer_streams 20
Разделите на число потоков и умножьте на планируемое количество — это и есть честный прогноз для вашего парка. Подробнее о метриках — Мониторинг и метрики.
Plane и нода на одном сервере#
Для небольшой установки это нормально. Единственное требование — не пересекаться портами: Plane занимает 443 (и 80 в режиме ACME), ноде дайте, например, 8090 и 8554.
| Сервис | Порт | Назначение |
|---|---|---|
| Plane | 8080 (http) или 443 (https) | API и админка |
| Plane | 80 | проверка Let's Encrypt в режиме acme |
| Нода | 8090 (пример) | HLS, плеер, API ноды |
| Нода | 8554 | RTSP-раздача |
Ресурсы при этом складываются: к требованиям ноды прибавьте требования Plane и PostgreSQL. Как только парк перерастает одну ноду — выносите Plane на отдельный сервер, чтобы нагрузка от видео не влияла на админку и базу.
Что дальше#
- Установка с нуля: Plane — контрол-плейн и база данных.
- Установка с нуля: Node — стриминговая нода и диски под архив.
- Проверка после установки — чек-лист готовности.