Производительность
Тюнинг хоста, ядра, io_uring и распределение камер по нодам.
Нода рассчитана на тысячи потоков и не перекодирует видео — она перепаковывает уже сжатые данные. Поэтому «медленно» почти никогда не означает нехватку процессора: чаще виноваты параметры ядра, ограничения systemd, диски или сеть. Разбирайте в том порядке, в котором идут разделы ниже.
Сколько ресурсов заложить изначально — Требования и подбор оборудования.
io_uring — основа ввода-вывода#
Нода использует io_uring и для сети, и для файловых операций. Без него она работать не будет.
uname -r # ядро 5.1 и выше sysctl kernel.io_uring_disabled # должно быть 0
| Значение | Что означает |
|---|---|
0 |
io_uring доступен — рабочее состояние |
1 |
Доступен только процессам с соответствующими правами |
2 |
Запрещён полностью — нода не запустится |
Установщик кладёт kernel.io_uring_disabled = 0 в /etc/sysctl.d/99-hastreamer.conf. Если
политика безопасности дистрибутива переопределяет это значение позже (файл с большим номером),
уберите переопределение — иначе после перезагрузки нода встанет.
В журнале ноды при старте видно, удалось ли применить тюнинг:
sudo journalctl -u hastreamer-cctv-node -b | grep -i 'tune:' # tune: applied … — параметры применены # tune: ⚠ host is not optimally tuned … — далее перечислены команды, которые нужно выполнить
Рабочие ядра#
Параметр cores в node.conf определяет, сколько ядер обслуживают медиа.
| Значение | Смысл |
|---|---|
0 |
Все производительные ядра — правильное значение по умолчанию |
N |
Ровно N ядер, начиная с самых быстрых |
cores 1 не означает «одно ядро на поток»Это означает, что вся работа со всеми камерами будет выполняться на одном ядре. На парке
из сотни камер такая нода упрётся в 100 % одного ядра, пока остальные простаивают, и видео
начнёт рассыпаться. Если не уверены — ставьте 0.
Менять удобнее из админки: Ноды → нода → Сеть и TLS → Рабочие ядра. Значение применяется при следующем перезапуске ноды, а не сразу.
Оставьте хосту запас: если на сервере, кроме ноды, работает Plane, база или что-то ещё, задайте
cores меньше, чем всего ядер, — тогда системные задачи не будут конкурировать с обработкой
медиа.
Параметры ядра#
Установщик ноды кладёт /etc/sysctl.d/99-hastreamer.conf и применяет его. Ключевые параметры:
| Параметр | Значение | Зачем |
|---|---|---|
kernel.io_uring_disabled |
0 |
Основа ввода-вывода |
net.ipv4.ip_local_port_range |
1024 65535 |
Диапазон исходящих портов: каждая камера — это исходящее подключение |
net.core.netdev_max_backlog |
50000 |
Очередь пакетов на приём; при значении по умолчанию пакеты теряются на всплесках |
net.core.somaxconn |
65535 |
Очередь входящих подключений при массовом открытии мозаики |
net.core.rmem_max / wmem_max |
16777216 |
Потолок буферов сокета |
net.ipv4.tcp_rmem / tcp_wmem |
автонастройка до 16 МиБ | Запас для окна TCP |
net.ipv4.udp_rmem_min / udp_wmem_min |
16384 |
Минимум на каждый UDP-сокет |
net.ipv4.tcp_tw_reuse, tcp_fin_timeout |
1, 15 |
Быстрое переиспользование соединений при частых подключениях зрителей |
fs.file-max, fs.nr_open |
2097152 |
Потолок файловых дескрипторов |
vm.swappiness |
1 |
Не вытеснять буферы видео в подкачку |
vm.max_map_count |
1048576 |
Много отображений памяти под кольцевые буферы |
net.ipv4.tcp_ecn |
0 |
ECN на некоторых маршрутах ломает установление TLS-соединения |
# применить после правки sudo sysctl --system # проверить фактические значения sysctl net.ipv4.ip_local_port_range net.core.somaxconn net.core.rmem_max vm.swappiness
Дополнительно нода при старте под root переводит регулятор частоты процессора в режим
performance — без него частота «плавает» и появляются рывки на всплесках нагрузки.
Ограничения systemd#
Юнит ноды поставляется с ограничениями, рассчитанными на среднюю установку:
| Параметр | Значение в юните ноды | Когда менять |
|---|---|---|
LimitNOFILE |
1048576 |
Обычно достаточно |
LimitMEMLOCK |
infinity |
Не менять — нужен io_uring |
MemoryHigh / MemoryMax |
6G / 8G |
Поднимать на крупных парках |
TasksMax |
8192 |
При очень большом числе потоков |
CPUQuota |
не задан | Задать, если нода делит сервер с другими службами |
MemoryMax=8G — жёсткий потолок cgroup. Нода, которой по расчёту нужно 16–32 ГБ, упрётся в
него: сначала начнётся вытеснение, затем процесс будет остановлен ядром. Поднимите пределы
через drop-in — файл юнита при обновлении перезаписывается, а drop-in сохраняется:
sudo systemctl edit hastreamer-cctv-node
[Service] MemoryHigh=24G MemoryMax=32G
sudo systemctl daemon-reload sudo systemctl restart hastreamer-cctv-node systemctl show hastreamer-cctv-node -p MemoryMax -p MemoryHigh
Тот же приём применим к Plane (MemoryHigh=1G / MemoryMax=2G по умолчанию) — их стоит
поднять на установках с большим числом событий и вложений.
Диски под архив#
| Правило | Почему |
|---|---|
| Отдельный раздел, не корневой | Заполнение архива не должно останавливать систему |
| ext4 или XFS | Проверенные файловые системы для крупных файлов |
| Отдельный физический диск (или массив) от системного | Запись архива не конкурирует с журналами и базой |
Порог вытеснения evict_at_percent ≈ 90 % |
Оставляет место на завершение текущих записей |
| Длительность сегмента 15/30/60 минут | Короче — слишком много файлов, длиннее — дольше восстановление |
Признаки, что диск не справляется: рост задержки записи, рывки при просмотре архива, растущая очередь ввода-вывода. Проверить:
df -h /mnt/dvr # заполнение iostat -x 5 3 # %util около 100 — диск загружен полностью du -sh /mnt/dvr # реальный объём записей
Хранилища добавляются и настраиваются только из Plane — см. Хранилища DVR. Сетевые файловые системы под архив использовать не стоит: запись идёт непрерывно и чувствительна к задержкам.
Сеть#
- Транспорт до камер — по умолчанию
source_transport tcp. Это надёжный вариант, при котором параметры UDP-приёма вообще не используются. Переводите камеры на UDP только при явной необходимости и с пониманием последствий. rtp_max_payload 1200— безопасный размер полезной нагрузки RTP: проходит через VPN-туннели без фрагментации. В однородной локальной сети с MTU 1500 значение можно поднять примерно до 1460.- Раздельные интерфейсы — на крупных установках развести трафик камер и трафик зрителей по разным сетевым интерфейсам, чтобы всплеск зрителей не влиял на приём.
- Загрузка канала — планируйте не более 50–60 % от номинала интерфейса.
Если камеры забираются по UDP и в метриках растут потери, увеличивайте по одному параметру
за раз: udp_ingest_pool_slots, затем udp_ingest_rcvbuf, затем udp_ingest_shards. Все они
применяются только после перезапуска — описание в node.conf.
Как понять, что нода перегружена#
| Признак | Где виден | Что делать |
|---|---|---|
| CPU процесса приблизился к числу рабочих ядер | Карточка ноды, hastreamer_process_cpu_cores |
Добавить ядра или перенести часть камер на другую ноду |
| Загружено одно ядро, остальные простаивают | Тепловая карта ядер | Проверить cores — скорее всего стоит 1 |
| Растут потери ядра и очереди | Карточка ноды, hastreamer_udp_ingest_*_total |
Параметры ядра, буферы UDP, переход на TCP-транспорт |
| Растёт «RX в очереди» | Карточка ноды | Нода не успевает разбирать входящий поток — снизить нагрузку |
RSS приблизился к MemoryMax |
hastreamer_process_rss_bytes |
Поднять ограничения systemd (см. выше) |
| Задержка приёма растёт у многих потоков | hastreamer_stream_ingest_latency_ms |
Сеть до камер или перегрузка ноды |
| Открытые FD растут без роста числа камер | Карточка ноды, hastreamer_open_fds |
Проверить журналы на переподключения |
Метрики и способы их сбора — Мониторинг и метрики.
Распределение камер по нодам#
Ноды масштабируются горизонтально: две ноды по 250 камер всегда предпочтительнее одной на 500.
| Правило | Причина |
|---|---|
| Держите запас 30–50 % по CPU и памяти | Всплески при массовых переподключениях |
| Группируйте камеры по площадкам | Трафик не ходит между площадками лишний раз |
| Не превышайте лимит потоков лицензии | Сверх лимита новые потоки не принимаются — Лицензирование |
| Учитывайте ёмкость дисков ноды | Глубина архива ограничена именно её дисками |
| Одна отказавшая нода = потеря только своих камер | Отказ распределяется, а не затрагивает всё |
Камера привязывается к ноде в её настройках (Камеры → камера → Размещение), там же доступен подбор ноды по текущей загрузке — см. Настройка камер.
Чего делать не нужно#
- Не отключайте io_uring «для безопасности» — нода без него не работает.
- Не ставьте архив на корневой раздел — переполнение остановит и систему, и запись.
- Не выставляйте
cores 1в надежде «ограничить нагрузку»: это создаёт узкое место. - Не рассчитывайте нагрузку по разрешению камер — значение имеет только битрейт.
- Не правьте управляемую Plane часть
node.conf— она будет восстановлена при следующем применении конфигурации. Правьте только верхнюю, системную часть файла.