【问题标题】:Linux non-persistent backing store for mmap()用于 mmap() 的 Linux 非持久性后备存储
【发布时间】:2018-09-05 19:37:12
【问题描述】:

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

我正在研究我可以把事情扩大到多远,我遇到的一个问题是最终(当我通过使服务器的配置越来越大来对服务器进行压力测试时),这个数据结构变得足够大导致内存不足的问题,然后OOM杀手出现,随之而来的是普遍的不满。请注意,Linux 的这种嵌入式配置没有启用交换,我无法(轻松)启用交换分区。

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

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

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

或者,如果 Linux 没有任何内置的 auto-temp-file-cleanup 功能,是否存在人们使用的“最佳实践”来确保大型临时文件不会最终填满驱动器无意间变得执着?

请注意,AFAICT 只是将文件放在 /tmp 中对我没有帮助,因为 /tmp 使用的是 RAM 磁盘,因此与简单地分配进程内堆存储相比,不会给我任何 RAM 使用优势。

【问题讨论】:

  • 如果你有文件存储,你可以使用交换文件而不是交换分区。

标签: c++ linux mmap temporary-files file-management


【解决方案1】:

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

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

为了速度,您可能想帮助 Linux 管理其页面缓存。您可以使用posix_madvisePOSIX_MADV_WILLNEED 来建议内核将数据分页并使用POSIX_MADV_DONTNEED 来建议内核释放页面。

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

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

【讨论】:

  • 很好的答案,谢谢!鉴于我将把这些数据视为在 RAM 中(即不需要持久性),我是否有任何理由关心数据何时/如何/是否刷新到磁盘?
  • @JeremyFriesner:可能是因为假设您没有足够的物理 RAM...内核将根据其缓存逻辑刷新和加载页面,但您可能可以做得更好(很多)因为您知道自己的访问模式。特别是,如果您知道阵列的某些部分是“冷的”,您可能可以通过将其显式同步到磁盘并建议内核回收这些页面来提高性能。如果你的访问模式真的是随机的,那么当然,让内核来处理它。
【解决方案2】:

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

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

我相信这种行为是 posix 强制要求的,因此它适用于任何类似 unix 的系统。即使在硬重启时,空间也会被回收。

【讨论】:

    【解决方案3】:

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

    更多详情请看这篇帖子:What happens to an open file handle on Linux if the pointed file gets moved, delete

    【讨论】:

    • 这是POSIX defined behavior,它适用于所有普通fs和Unix操作系统
    • @thatotherguy:是的,但我敢打赌,并非所有文件系统驱动程序都以确保这些文件被正确清理而无需额外工作的方式实现它。例如,FAT32 文件系统如何做到这一点? This question 表示硬重启可能会在此文件系统上留下孤立文件。既然他说的是flash,那谁知道用的是哪个文件系统呢?
    • 在 fat32 上运行良好。孤立文件在所有 FS 上都是一个问题,它们会被 fsck 或日志恢复清理
    猜你喜欢
    • 1970-01-01
    • 2017-07-25
    • 1970-01-01
    • 2014-05-05
    • 2017-04-26
    • 2010-10-05
    • 1970-01-01
    • 2010-11-30
    • 1970-01-01
    相关资源
    最近更新 更多