Архивация в fMP4 и прямой ввод-вывод в Linux
Движок записи в RUSEON Core (internal/recorder/) обеспечивает надежное круглосуточное сохранение видеоархива. В отличие от традиционных NVR, сохраняющих монолитные MP4 с индексом moov в конце файла, RUSEON упаковывает видео исключительно во фрагментированный MP4 (fMP4).
1. Преимущества фрагментированного MP4 (fMP4)
Обычные файлы MP4 пишут медиаданные в mdat, а индексную таблицу (moov) формируют только при закрытии файла. При отключении питания незакрытый файл повреждается.
Во фрагментированном MP4 (fMP4):
- Инициализирующий сегмент (
ftyp+moov) записывается в самом начале (содержит параметры кодека SPS/PPS). - Видео пишется последовательностью независимых фрагментов (
moof+mdat). - Каждый фрагмент содержит один GOP, начинающийся с I-кадра.
- При аварийном отключении питания все завершенные фрагменты на диске сохраняют 100% целостность.
2. Сброс кеша страниц ядра Linux (CacheDropper)
При записи десятков камер стандартная буферизация ОС вызывает проблемы:
- Page Cache Thrashing: Ядро Linux забивает RAM "грязными страницами".
- Зависания I/O: Сброс гигабайтов данных блокирует дисковые контроллеры.
RUSEON Core решает это в internal/recorder/recorder.go через прямое вытеснение страниц:
go
// 1. Запись части fMP4 на диск
_ = part.Marshal(file)
// 2. Указание ядру Linux вытеснить страницы из RAM
if dropper, ok := file.(registry.CacheDropper); ok {
_ = dropper.DropCache()
}unix.SyncFileRange(fd, offset, length, unix.SYNC_FILE_RANGE_WRITE): Неблокирующий фоновый сброс страниц на диск.unix.Fadvise(fd, offset, length, unix.FADV_DONTNEED): Освобождение оперативной памяти ядра без ожидания системных таймеров.
3. Ротация файлов и жизненный цикл
Ротация файлов выполняется каждые 1 час по границе ключевого кадра:
- Активный файл:
recordings/{camera_id}/2026-08-23_15-04-05_ongoing.mp4 - Завершенный файл:
recordings/{camera_id}/2026-08-23_15-04-05_to_16-04-05.mp4 - Восстановление при старте: Незавершенные файлы автоматически восстанавливаются при запуске сервера
cmd/server/main.go.
4. Пример конфигурации в YAML
yaml
server:
record_retention_days: 14 # Глобальный срок хранения архива в днях
cameras:
- id: "cam-01"
url: "rtsp://admin:pass@192.168.1.100:554/live"
record: true
retention_days: 7 # Индивидуальный ретеншн для камеры