Skip to content

Устранение Page Cache Thrashing и OOM при круглосуточной записи ​

Одна из самых опасных проблем при круглосуточной записи видео в Linux — вымывание кеша страниц ядра (Page Cache Thrashing) и аварийные остановки OOM Killer.


1. Первопричина: почему память в Linux переполняется при записи видео ​

При записи видеопотоков через стандартный дисковый ввод-вывод (os.File.Write() в Go или write() в C) ядро Linux не пишет данные на диск мгновенно.

Вместо этого:

  1. Linux кеширует каждый записанный байт: Ядро помещает видеоблоки в Page Cache (RAM) со статусом "грязных страниц".
  2. Отложенный сброс: Фоновые потоки ядра (pdflush/kswapd) сбрасывают страницы на диск пачками.
  3. Кризис вытеснения кеша: Поток видео непрерывен. Ядро удерживает страницы в RAM, пока до 90%+ физической памяти не займет кеш.
  4. Авария OOM: Когда соседнему процессу (БД, WebRTC-энкодеру или GC Go) срочно требуется память, Linux вынужден останавливать I/O для освобождения страниц или вызывать OOM Killer, аварийно завершая видеосервер.

2. Архитектурное решение RUSEON Core: POSIX_FADV_DONTNEED ​

В RUSEON Core эта проблема решена на уровне системных вызовов ядра без небезопасных хаков ОС:

  1. Запись блоками fMP4: Видео сохраняется независимыми фрагментами.
  2. Явное вытеснение страниц: Сразу после завершения записи фрагмента RUSEON вызывает интерфейс CacheDropper:
go
// 1. Запись части fMP4 на диск
_ = part.Marshal(file)

// 2. Указание ядру Linux немедленно вытеснить страницы из RAM
if dropper, ok := file.(registry.CacheDropper); ok {
    _ = dropper.DropCache()
}

Практические результаты: ​

  • Отсутствие накопления кеша: Расход памяти остается строго плоским (~471 МБ RSS при 600 камерах) в течение сотен дней непрерывной работы.
  • Предсказуемый ввод-вывод: Устраняются всплески I/O Wait и зависания системы.
  • Работа без root-прав: Решение стабильно функционирует в Docker-контейнерах и Kubernetes-подах без привилегированного режима.

Связанная документация ​

Released under the MIT License.