用于mmap()的Linux非持久性后备存储

问题描述 投票:0回答:3

首先,有一点激励背景信息:我有一个基于C ++的服务器进程,它运行在嵌入式基于ARM / Linux的计算机上。它运行得很好,但作为其操作的一部分,它创建了一个相当大的固定大小的数组(例如几十到几百兆字节)的临时/非持久状态信息,它当前保留在堆上,并且它访问和/或不时更新该数据。

我正在调查我可以扩展的范围,我遇到的一个问题是最终(当我通过使其配置越来越大而对服务器进行压力测试时),这个数据结构变得足够大,导致 - 记忆问题,然后OOM杀手出现,随之而来的是一般的不快乐。请注意,Linux的这种嵌入式配置没有启用交换,我无法(轻松)启用交换分区。

我对如何改善问题的一个想法是在计算机的本地闪存分区上分配这个大型数组,而不是直接在RAM中,然后使用mmap()使它看起来像服务器进程,就像它仍在RAM中一样。这将大大减少RAM的使用,我希望Linux的文件系统缓存可以掩盖大部分产生的性能成本。

我唯一真正关心的是文件管理 - 特别是,我想避免任何用“孤儿”后备存储文件填充闪存驱动器的机会(即其进程不再存在的旧文件,但文件仍然存在,因为它的创建过程崩溃或其他一些错误忘记在退出时删除它)。我还希望能够在同一台计算机上同时运行多个服务器实例,而不会相互干扰实例。

我的问题是,Linux是否有任何内置工具来处理这种用例?我特别想象一种标记文件(或mmap()句柄或类似文件)的方法,这样当创建进程的文件退出或崩溃时,操作系统会自动删除文件(类似于Linux已经自动化的方式)当进程退出或崩溃时,恢复进程分配的所有RAM。

或者,如果Linux没有任何内置的自动临时文件清理功能,那么人们会使用“最佳实践”来确保大型临时文件不会因无意中变为填满驱动器执着?

请注意,AFAICT只是将文件放在/ tmp中对我没用,因为/ tmp使用的是RAM磁盘,因此不会给我任何RAM使用优势,而不仅仅是分配进程内堆存储。

c++ linux mmap temporary-files file-management
3个回答
3
投票

是的,我一直这样做......

open文件,unlink它,使用ftruncate或(更好)posix_fallocate使其大小合适,然后使用mmapMAP_SHARED将其映射到您的地址空间。如果你愿意,你可以立即close描述符;内存映射本身将保留文件。

为了提高速度,您可能会发现希望帮助Linux管理其页面缓存。你可以使用posix_madvisePOSIX_MADV_WILLNEED建议内核分页数据和POSIX_MADV_DONTNEED建议内核释放页面。

您可能会发现last不能按照您想要的方式工作,尤其是对于脏页面。您可以使用sync_file_range显式控制刷新到磁盘。 (虽然在这种情况下,您将希望保持文件描述符处于打开状态。)

所有这些都是完全标准的POSIX,除了特定于Linux的sync_file_range


2
投票

是的,您创建/打开文件。然后你remove()文件的文件名。

该文件仍将由您的进程打开,您可以像打开的文件一样读/写它,并且当打开文件的进程退出时它将消失。

我相信这个行为是由posix强制执行的,因此它可以在任何类似unix的系统上运行。即使在硬重启时,该空间也将被回收。


1
投票

我相信这是特定于文件系统的,但大多数Linux文件系统允许删除打开的文件。该文件将一直存在,直到它的最后一个句柄关闭。我建议你打开文件,然后立即将其删除,当你的进程因任何原因退出时,它会自动清理。

有关详细信息,请参阅此帖子:What happens to an open file handle on Linux if the pointed file gets moved, delete

© www.soinside.com 2019 - 2024. All rights reserved.