什么时候应该使用/dev/shm/?什么时候应该使用/tmp/?我可以一直依靠他们都在Unices上吗?

#1 楼

/dev/shm是一个临时文件存储文件系统,即tmpfs,它使用RAM作为后备存储。
它可用作促进IPC的共享内存实现。

来自Wikipedia:


最近的2.6 Linux内核版本已开始以ramdisk形式提供/ dev / shm作为共享内存,更具体地说是世界可写目录,该目录以/ etc / default / tmpfs中定义的限制存储在内存中。
/ dev / shm支持在内核配置文件中是完全可选的。
Fedora和Ubuntu发行版中都默认包含它,在Pulseaudio应用程序中使用最广泛。


/tmp是文件系统层次结构标准中定义的临时文件的位置,几乎所有Unix和Linux发行版都遵循该文件。

由于RAM的速度明显快于磁盘存储,因此您可以使用/dev/shm代替/tmp如果您的过程是I / O密集型并且广泛使用临时文件,则可以提高性能。

要回答您的问题:不,您不能总是依赖/dev/shm的存在,当然也不能依赖捆绑内存的机器。除非您有充分的理由使用/tmp,否则应使用/dev/shm

请记住,/tmp可以是/文件系统的一部分,而不是单独的安装文件,因此可以根据需要进行扩展。 /dev/shm的大小受系统上过多的RAM限制,因此,您更有可能在此文件系统上用完空间。

评论


我将使用它将命令的标准错误输出的输出重定向到文件。然后,我将读取此文件并进行处理。我将执行数千次(这是循环构造条件的一部分)。我认为在这种情况下,记忆会很好。但我也希望它具有便携性。我想我会检查/ dev / shm是否存在,如果存在,请使用它,或者回退到/ tmp。听起来不错吗?

–已删除
2009年9月23日在16:04

我还要添加一个检查/ dev / shm的最小大小和当前使用级别,以防止无意中将其填满。

–user4358
09年9月23日在21:01

在Linux 2.6及更高版本中,需要安装/ dev / shm才能使POSIX共享内存系统调用(如shm_open())正常工作。换句话说,如果未安装某些程序,则该程序将中断-应该如此。它不仅是RAM磁盘。因此,您应确保/ dev / shm中的某些内容是免费的。

– EdH
2012年11月30日在21:07



使用/ dev / shm不会提高性能。 / dev / shm是磁盘(交换)支持的内存(tmpfs)。 / var / tmp是磁盘(磁盘文件系统)支持的内存(磁盘缓存)。在实践中,性能大致相同(tmpfs略有优势,但不足以解决问题)。 / tmp是否为tmpfs,取决于管理员的配置方式。没有充分的理由在脚本中使用/ dev / shm。

–吉尔斯'所以-不再是邪恶的'
2013年6月18日7:13



@GaretClaborn有很多充分的理由使用交换支持的内存,但这被称为普通进程内存。如果您使用的是文件,则称为文件系统,并且所有文件系统均为内存(缓存),如果文件系统类似于tmpfs,则由swap支持。在交换空间和其他存储区域之间分配磁盘空间通常是管理员真正需要的。如果应用程序希望将文件保留在RAM中,则/ tmp是正常位置(使用$ TMPDIR覆盖)。使/ tmp由交换,其他磁盘空间或什么都不做的选择是管理员的。

–吉尔斯'所以-不再是邪恶的'
2014年6月5日14:09

#2 楼

按照tmpfs可能的降序排列:
┌───────────┬──────────────┬────────────────┐
│ /dev/shm  │ always tmpfs │ Linux specific │
├───────────┼──────────────┼────────────────┤
│ /tmp      │ can be tmpfs │ FHS 1.0        │
├───────────┼──────────────┼────────────────┤
│ /var/tmp  │ never tmpfs  │ FHS 1.0        │
└───────────┴──────────────┴────────────────┘

由于您询问的是Linux特定的tmpfs挂载点,而不是可移植定义的目录(可能是tmpfs)(取决于您的sysadmin和发行版的默认设置),因此您的问题有两个方面,其他答案对此有不同的强调:

适当使用各种tmp目录

适当使用tmpfs



适当使用各种tmp目录
根据古老的文件系统层次结构标准以及Systemd关于此问题的说法。

如有疑问,请使用/tmp
请使用/var/tmp进行操作重新启动后应持续存在的数据。
对于可能无法轻松放入RAM的大数据使用/var/tmp(假设/var/tmp有更多可用空间-通常是一个合理的假设)。
仅将/dev/shm用作副作用调用shm_open()。预期的目标对象是无限覆盖的缓冲区。因此,这适用于内容易失且不会很大的长寿命文件。
绝对不要对可执行文件(任何类型)使用/dev/shm,因为它通常是noexec
如果仍然有疑问,请提供用户覆盖的一种方式。为使惊喜最少,请像mktemp一样使用并尊重TMPDIR环境变量。

tmpfs擅长的地方
重要的是要说tmpfs真正擅长的地方首先是隐藏在旋转的磁盘上非常重要的性能错误。因此,如果修复它是一种选择,那么这当然是对tmpfs的不当使用:
fsync是tmpfs上的无操作项。此系统调用告诉OS刷新与文件关联的页面缓存,一直到刷新相关存储设备的写缓存,同时阻止发布它的程序完全没有进展–这是非常粗糙的写障碍。仅在存储协议不是考虑到事务的情况下,它才是必备的工具。缓存首先是使程序能够执行数百万次对文件的小写操作,而无需注意写入存储设备的实际速度—所有实际写入都是异步发生的,或者直到调用fsync为止,这是唯一可以直接由程序感觉到写入性能的地方。
因此,如果您发现自己使用tmpfs(或eatmydata)只是为了击败fsync,那么您(或该链中的其他开发人员)正在做错事。这意味着针对您的目的,对存储设备进行的事务处理不必要地精细化-您显然愿意跳过一些保存点以提高性能,因为您现在已经破坏了所有保存点-很少会有最好的妥协。同样,在交易性能领域中,拥有SSD的一些最大好处是–与旋转磁盘可能要消耗的SSD相比,任何物超所值的SSD都将具有超凡脱俗的性能(7200 rpm = 120 Hz,如果没有其他说明正在访问它)。闪存卡在此指标上也相差很大(这是在顺序性能上的折衷,而SD卡的等级仅考虑后者)。因此请当心,拥有快速SSD的开发人员不要强迫您的用户进入此用例!
想听一个荒谬的故事吗?我的第一个fsync课程:我从事一项工作,涉及定期将一堆Sqlite数据库(称为测试用例)“升级”到不断变化的当前格式。 “升级”框架将运行一堆脚本,每个脚本至少进行一次事务以升级一个数据库。当然,我并行升级了数据库(并行升级了8个数据库,因为我拥有强大的8核CPU)。但是,正如我发现的那样,并行化速度完全没有问题(因为这完全是IO约束),因此根本没有并行化加速。有趣的是,将升级框架包装在一个脚本中,该脚本将每个数据库复制到/dev/shm,在那里进行了升级,然后将其复制回磁盘,速度快了100倍(并行8个)。另外,PC还可在升级数据库时使用。
tmpfs适用的地方
tmpfs的适当使用是为了避免不必要地写入易失性数据。有效禁用写回,就像在常规文件系统上将/proc/sys/vm/dirty_writeback_centisecs设置为infinity一样。
这与性能没有多大关系,并且与滥用fsync相比,失败的关注要小得多:写回超时决定了磁盘内容更新的延迟时间在页面缓存内容之后,默认值为5秒,这对于计算机而言是很长的时间–应用程序可以在页面缓存中根据需要频繁覆盖文件,但是磁盘上的内容大约每5秒更新一次。除非应用程序使用fsync强制通过它。考虑一下应用程序这次可以输出一个小文件多少次,您会明白为什么对每个单个文件进行fsync会是一个更大的问题。
tmpfs不能为您提供什么帮助

阅读性能。如果您的数据很热(最好考虑将其保存在tmpfs中),那么无论如何您都会访问页面缓存。区别在于不访问页面缓存时;如果是这种情况,请转到下面的“ Where tmpfs sux”。
短期文件。这些可以在被写出之前将其全部生命保存在页面缓存中(作为脏页面)。除非您用fsync强制使用它。

tmpfs sux
保存冷数据。您可能会倾向于认为从交换中提供文件与普通文件系统一样有效,但是有两个原因导致它不起作用:

最简单的原因:没有什么当代的存储设备(无论是基于硬盘还是闪存)都比读取由适当的文件系统整齐组织的相当连续的文件更爱。交换4KiB块不可能对此有所改善。
隐藏的成本:交换。 Tmpfs页面很脏-它们需要写到某个地方(以便交换)才能从页面缓存中删除,而不是可以立即删除的文件支持的干净页面。这是对争用内存的所有其他事物的额外写惩罚–在与使用这些tmpfs页面不同的时间影响其他事物。


评论


在我的Ubuntu 14.04中,/ dev / shm链接到/ run / shm,根据命令df,文件系统为“ none”。大小约为2G。

– jarno
16 Dec 14'在8:41

@jarno首先,节省tmpfs挂载点的数量,我称之为实现细节。其次,不要让设备名称使您感到困惑–在/ proc / mounts中查找(这是查找的正确位置),您会看到类型是“ tmpfs”,而设备在这里是“无”。是的,设备名称在tmpfs中没有任何意义–如果愿意,您可以挂载-t tmpfs“ jarno很棒” / mnt / jarno!第三,默认大小是RAM的一半-我敢打赌,你有4GiB RAM。

–user2394284
16 Dec 22'在19:04

是否有分配固定RAM大小并承诺永远不使用交换的选项?

–palswim
17年7月28日在21:44

@palswim:那将是一个虚拟磁盘。除了tmpfs的前身不支持交换外,我在tmpfs中看不到该选项。进程可以将其页面锁定在ram中,这比将tmpfs页面锁定在ram中要疯狂的多,考虑到OOM杀手无法释放后者,如果内存不足。

–user2394284
17年8月17日14:18



#3 楼

好的,这就是现实。

tmpfs和普通文件系统都是磁盘上的内存缓存。

tmpfs使用内存和交换空间作为后备存储,文件系统使用特定的磁盘区域,文件系统的大小均不受限制,一台机器上有200GB的tmpfs是很有可能的如果您有足够的交换空间,则RAM少于GB。

区别在于何时将数据写入磁盘。对于tmpfs,仅在内存太满或不太可能很快使用数据时才写入数据。 OTOH大多数正常的Linux文件系统都被设计为在磁盘上始终具有或多或少一致的数据集,因此,如果用户拔出插头,他们不会丢失任何东西。

就我个人而言,我已经习惯了不会崩溃的操作系统和UPS系统(例如:笔记本电脑电池),因此我认为ext2 / 3文件系统在5-10秒的检查点上过于偏执间隔。 ext4文件系统最好具有10分钟的检查点,但它会将用户数据视为第二类并且不对其进行保护。 (ext3相同,但是由于5秒检查点而没有注意到它)

这种频繁的检查点意味着不必要的数据正在不断地写入磁盘,即使对于/ tmp也是如此。

因此,结果是您需要创建与/ tmp一样大的交换空间(即使必须创建一个swapfile),并使用该空间将所需大小的tmpfs挂载到/ tmp上。

切勿使用/ dev / shm。

除非您将其用于非常小(可能是mmap'd)的IPC文件,并且您确定它存在(这不是标准),并且计算机具有足够的内存+可用交换空间。

评论


同意,除了结论“永远不要使用/ dev / shm”。如果您根本不想将文件写入磁盘,并且希望最大程度地减少磁盘I / O,则要使用/ dev / shm。例如,我需要从FTP服务器下载非常大的zip文件,将其解压缩,然后将其导入数据库。我将其解压缩到/ dev / shm,以便对解压缩和导入操作而言,HDD只需要执行一半的操作,而不用在源和目标之间来回移动。它极大地加快了该过程。这是很多例子,但我同意这是一种利基工具。

–内森·舒展(Nathan Stretch)
2014年12月11日23:13

参见0pointer.net/blog/projects/tmp.html。您可以使用$ XDG_RUNTIME_DIR临时存储下载的文件。我知道这个答案已有很多年了,所以我发布的链接也是如此。

– Soumya Kanti
20-04-22在8:24

#4 楼

将/ tmp /用于临时文件。当需要共享内存(即通过文件进行进程间通信)时,请使用/ dev / shm /。

您可以依赖/ tmp /在那里,但是/ dev / shm /是相对较新的Linux东西。

评论


也没有表现方面吗? / dev / shm最常作为tmpfs卷挂载,实际上是作为RAM磁盘挂载?

–已删除
09年9月23日在9:37

您也可以将/ tmp挂载为tmpfs文件系统,我在上网本上这样做是通过减少对(慢速)SSD的写入来加快某些速度。当然,这样做有弊端(主要是使用RAM,但是我的上网本的RAM远远超出了通常所需的内存)。

– David Spillett
09年9月23日在10:55

对于我的特定情况,我将其用于某种过程通信。我从应用程序捕获标准错误的输出并对其内容进行操作(而且我仍然需要保持标准输出不变,因此我无法执行任何1> / dev / null 2>&1。我会执行数千次,因此一个tmpfs会很好。但是,如果我发布脚本,我就不能依靠tmpfs用于/ tmp,因为我认为它并不常见。如果对于/ dev / shm更常见,那么对我来说更好。寻找有关便携性等的准则

–已删除
09-09-23 16:00

#5 楼

另一个应该使用/ dev / shm(对于Linux 2.6及更高版本)的时间是,您需要保证tmpfs文件系统,因为您不知道是否可以写入磁盘。

监视系统我熟悉在构建报告以提交到中央服务器时需要写出临时文件。在实践中,更有可能阻止某些东西写入文件系统(磁盘空间不足或潜在的RAID故障使系统进入硬件只读模式),但您仍然可以保持警惕而不是像某些东西使所有可用内存急剧增加,以致tmpfs将不可用(并且包装盒不会失效)。在这种情况下,监视系统将更喜欢写到RAM,以便潜在地能够发送有关磁盘已满或硬件已死/快死的警报。

#6 楼

/ dev / shm用于共享虚拟内存系统特定的设备驱动程序和程序。

如果要创建需要虚拟内存堆的程序,则该程序应映射到虚拟内存。这翻倍了,因此,如果您需要多个进程或线程才能安全地访问该内存。

事实是,仅仅因为驱动程序为此使用了特殊版本的tmpfs,并不意味着您应该将其用作通用tmpfs分区。相反,如果您要为临时目录创建一个tmpfs分区,则应该创建另一个。

#7 楼

在PERL中,任何机器(均运行Linux Mint)上的最小内存为8GB,我认为这是一个好习惯,即使用/ dev /进行数百万次的基于DB_File的复杂算法(文件中的数据结构)的数百万次读写操作shm

在其他语言中,并不是到处都有,避免使用批处理来避免网络传输的开始和停止(在位于客户端-服务器环境中的服务器上的本地文件中工作)某种类型的文件,我将立即将整个文件(300-900MB)复制到/ dev / shm,将输出结果运行到/ dev / shm,将结果写回到服务器,然后从/ dev / shm删除

当然,如果我的RAM更少,我就不会这样做。通常,/ dev / shm的内存文件系统读取的大小是可用RAM的一半。但是,RAM的常规使用是恒定的。因此,您实际上无法在2GB或更小的设备上执行此操作。为了将夸张的说法夸张,RAM中经常有一些东西,甚至系统也无法很好地报告。

评论


(我认为这是本来要求提供的精神。)我的基本意思是,只要我有足够的内存,就可以将/ dev / shm用作RAM磁盘。如果这样做效率低下,那不应该阻止您这样做,而应该引发类似“我如何在Linux上拥有ram磁盘?”之类的问题。答案是/ dev / shm

–大卫·格罗夫(David Grove)
15年9月27日在21:44