Непостоянное резервное хранилище Linux для mmap () - PullRequest
0 голосов
/ 05 сентября 2018

Сначала небольшая мотивирующая справочная информация: у меня есть серверный процесс на C ++, работающий на встроенном компьютере на базе ARM / Linux. Он работает довольно хорошо, но в рамках своей работы он создает довольно большой массив фиксированного размера (например, от десятков до сотен мегабайт) временной / непостоянной информации о состоянии, которую он в настоящее время хранит в куче, и к которой он обращается и / или обновляет эти данные время от времени.

Я исследую, как далеко я могу масштабироваться, и одна проблема, с которой я сталкиваюсь, заключается в том, что в конечном итоге (когда я подвергаю стресс-тестирование сервера, увеличивая и увеличивая его конфигурацию), эта структура данных становится достаточно большой, чтобы вызвать проблемы нехватки памяти, и затем появляется убийца OOM, и общее несчастье наступает. Обратите внимание, что во встроенной конфигурации Linux не разрешен обмен, и я не могу (легко) включить раздел подкачки.

Одна идея, которая у меня есть, для решения этой проблемы, заключается в том, чтобы разместить этот большой массив в локальном флэш-разделе компьютера, а не непосредственно в ОЗУ, а затем использовать mmap (), чтобы он отображался в процессе сервера, как будто он все еще находится в БАРАН. Это значительно уменьшило бы использование ОЗУ, и я надеюсь, что кэш файловой системы Linux будет маскировать большую часть результирующих затрат производительности.

Мое единственное реальное беспокойство - управление файлами - в частности, я бы хотел избежать любых шансов на заполнение флэш-накопителя "бесхозными" файлами резервного копирования (т. Е. Старыми файлами, процессы которых больше не существуют, но файл все еще присутствует, потому что процесс его создания потерпел крах или по какой-то другой причине забыл удалить его при выходе). Я также хотел бы иметь возможность запускать несколько экземпляров сервера одновременно на одном компьютере, не мешая друг другу.

У меня вопрос: есть ли в Linux какие-либо встроенные средства для работы с такого рода сценариями использования? Я особенно представляю себе какой-нибудь способ пометить файл (или дескриптор mmap () или аналогичный), чтобы при выходе или сбое файла, создавшего процесс, ОС автоматически удаляла файл (аналогично тому, как Linux уже автоматически) восстанавливает всю оперативную память, выделенную процессу, когда процесс завершается или завершается сбоем).

Или, если в Linux нет встроенной функции автоматической очистки файлов, есть ли "лучший метод", который люди используют, чтобы гарантировать, что большие временные файлы не будут заполнять диск из-за непреднамеренно стать стойким?

Обратите внимание, что AFAICT, просто поместив файл в / tmp, мне не поможет, так как / tmp использует RAM-диск и, следовательно, не дает мне никакого преимущества в использовании RAM по сравнению с простым выделением динамической памяти в процессе.

Ответы [ 3 ]

0 голосов
/ 05 сентября 2018

Да, вы создаете / открываете файл. Затем вы remove() файл по имени файла.

Файл по-прежнему будет открыт вашим процессом, и вы сможете читать / записывать его, как и любой открытый файл, и он исчезнет, ​​когда завершится процесс с открытым файлом.

Я считаю, что такое поведение предписано posix, поэтому оно будет работать в любой системе, подобной Unix Даже при полной перезагрузке пространство будет восстановлено.

0 голосов
/ 05 сентября 2018

Да, и я делаю это все время ...

open файла, unlink его, используйте ftruncate или (лучше) posix_fallocate, чтобы сделать его нужного размера, затем используйте mmap с MAP_SHARED, чтобы сопоставить его с вашим адресным пространством. Затем вы можете close дескриптор немедленно, если хотите; само отображение памяти будет держать файл вокруг.

Для ускорения вы можете захотеть помочь Linux управлять кешем страниц. Вы можете использовать posix_madvise с POSIX_MADV_WILLNEED, чтобы посоветовать ядру выгружать данные, и POSIX_MADV_DONTNEED, чтобы посоветовать ядру освободить страницы.

Вы можете обнаружить, что последний не работает так, как вы хотите, особенно для грязных страниц. Вы можете использовать sync_file_range для явного управления записью на диск. (Хотя в этом случае вы захотите оставить дескриптор файла открытым.)

Все это совершенно стандартный POSIX, за исключением специфичного для Linux sync_file_range.

0 голосов
/ 05 сентября 2018

Я полагаю, что это зависит от файловой системы, но большинство файловых систем Linux позволяют удалять открытые файлы. Файл будет существовать до тех пор, пока последний дескриптор к нему не будет закрыт. Я бы порекомендовал открыть файл, а затем немедленно удалить его, и он будет автоматически очищен при выходе из процесса по любой причине.

Подробнее см. В этом посте: Что произойдет с дескриптором открытого файла в Linux, если указанный файл будет перемещен, удалите

...