在Linux上创建RAM磁盘


70

我有一台具有62GB RAM的机器,以及一个只有7GB的中继,所以我想我会创建一个RAM磁盘并在那里进行编译。我不是Linux专家。我在网上找到了创建RAM磁盘的说明:

mkfs -q /dev/ram1 8192

但我将8192更改为16777216,以尝试分配16GB的ram磁盘。

我收到以下错误:

mkfs.ext2: Filesystem larger than apparent device size.
Proceed anyway? (y,n) 

在这一点上,我被吓到了并被保释。

sudo dmidecode --type 17 | grep Size

表演

8x8192MB + 2048MB = 67584 MB

du/dev给人804K

那是问题吗?我可以克服这个/dev大小吗?


15
您尝试过tmpfs吗?它是RAM中的文件系统,不需要ext2。mount -o size=16G -t tmpfs none /mnt/tmpfs
t-8ch

可行!谢谢!但是到目前为止,还没有太大的提速:我认为我用来构建的工具仍在使用常规磁盘。我将更多的东西放在ram磁盘上。
Frank

3
将工具本身放在ramdisk上不会有太大区别,因为内核无论如何都会将它们缓存在ram中。
t-8ch

1
@goldilocks这是一个轶事证据,但是当使用Maven编译Java项目时,使用ramdisk可以大大提高速度。我想虽然这更多是因为查找时间而不是读取时间。
SpellingD

1
的/ dev / SHM,实际上/运行/ SHM可以使用; 它几乎总是在那里。
卡米尔·古德塞内

Answers:


78

在Linux上创建ram磁盘的最佳方法是tmpfs。它是ram中的文件系统,因此不需要ext2。您可以使用以下命令创建大小为16Gb的tmpfs:

mount -o size=16G -t tmpfs none /mnt/tmpfs

2
在我的系统上,/ mnt中什么都没有,它表示:ls:无法访问/ mnt / tmpfs:不存在此类文件或目录安装:安装点/ mnt / tmpfs不存在。有什么需要担心的吗?如果我只是简单地使用mkdir / mnt / tmpfs,那是否达到了目的(通过在常规磁盘上创建tmpfs-请不要大怒,我是一个初学者)。
Frank

9
您需要一个挂载点(目录)作为目标,因此在创建该目录(可以使用任何目录,现有内容被遮盖)之后,可以使用答案中的命令将其挂载。
t-8ch 2013年

1
tmpfs可能使用交换,您可能不希望在纯RAM磁盘中使用交换。
palswim

2
@RomanSusi tmpfs是文件类型(在-t之后传递)。“ none”是tmpfs不存在的后备设备(“磁盘”)
t-8ch,

1
值得注意的是,指定大小是可选的。默认为RAM的一半。指定更大的大小没有任何开销,它所做的只是设置上限,以防止意外使用所有RAM并杀死系统。
sourcejedi

20

Linux 在使用RAM方面非常有效。毫不奇怪,您几乎看不到任何加速tmpfs。工具(编译器,汇编器,链接器)是要读入内存(从而能够减慢处理速度)的最大组件,并且很长一段时间后,make它们会在启动时加载到内存中,永远不会离开。剩下的就是读取源代码了(除非严重地限制了内存,将结果写出来不会使您放慢速度)。同样,公用头文件将保留在周围,只有用户的源才需要读取。而且那不可能超过几兆字节。创建大型RAMdisk(甚至大量使用tmpfs)可能会减慢速度(通过限制构建内存,RAMdisk或之上的文件tmpfs 不能 可以直接从那里使用)。


1
什么!如何不能从那里直接使用它们?
卡扎尔克

它们在RAM中,但不是直接可用的格式。
vonbrand

2
真!怎么会这样?(请原谅我的迟钝。)
Kazark

8
@Kazark,用于处理内存中的可执行文件,使用特殊的数据结构。由于RAM磁盘tmpfs并不常用来存储可执行文件(RAM磁盘tmpfs是软盘极其缓慢的过去的美好时光,因此严格用于临时数据),因此没有人认为添加必要的丑陋黑客足够重要。
vonbrand

7
我尝试从tmpfs(RAM)文件系统运行rails代码,但完全没有发现任何区别。我确实希望有明显的区别,但是我对linux的出色表现感到失望。
Khaja Minhajuddin

6

问题在于,ramdisk的最大大小,更具体地说是可以通过ramdisk驱动程序访问的内存大小,是在编译时配置的,可以在引导时覆盖,但是一旦内核加载到内存中就保持不变。默认值可能以兆字节为单位。如果我没记错的话,在加载驱动程序后就保留了用于ramdisk的内存,则所有ramdisk的大小都相同,默认情况下大约有16个ramdisk。因此,甚至您都不需要16G的虚拟磁盘大小:-)

如另一个答案中所述,tmpfs是您要使用的。此外,将整个操作系统放在ramdisk / tmpfs中不会带来很多收益。只需将您的builddir复制到tmpfs并进行编译即可。您可能必须确保将所有临时结果也写入到tmpfs中的位置。


在您向它们写入内容之前,它们实际上不会使用任何内存。引导时间限制只是限制。即使填满一个,也可以用释放内存blockdev --flushbufs
psusi

@psusi:您能给我们更多信息吗?我只能找到提及ramdisk内存一旦声明就永远不会被回收的语句,例如在Documentation/blockdev/ramdisk.txt内核源代码中。在我的回答上:该文件还显示内存随内存消耗而增加,因此并非一次分配所有内存。
Bananguin 2013年

什么样的信息?您运行命令并释放了ram,假设您仍然没有将其挂载。
psusi 2013年

您怎么知道该命令执行了您所说的操作?它的手册页未确认该内容,并且可以理解内核源代码树中的文档与您的信息相矛盾。
Bananguin

6
我阅读了源代码,并通过尝试对其进行了验证。
psusi

3

引导后要制作一个大的ram磁盘,而不会弄乱内核参数,这似乎可行。使用tmpfs,创建文件,通过循环挂载,然后通过文件系统挂载:

mount -t tmpfs -o size=200M tmpfs temp/
cd temp/
dd if=/dev/zero of=disk.img bs=1M count=199
losetup /dev/loop0 disk.img
mkfs.ext4 /dev/loop0
mount /dev/loop0 temp2/

可能会在多个不同的层次上造成性能损失……但是至少它能起作用。


3

除了tmpfs和之外ramfs,另一个选择是/dev/ram0块设备。在最新的Ubuntu版本上,默认情况下不存在此设备,但可以通过创建modprobe brd

这种方法更具可预测性,因为它创建了一个真实的ext4文件系统,并且从未超出您指定的限制。但是它需要采取更多步骤来设置,并且使用RAM的效率较低。

使用brd内核模块(/ dev / ram0)

要创建和初始化4GB RAM磁盘:

mkdir /ramdisk

modprobe brd rd_nr=1 rd_size=$((4 * 1048576))
mkfs.ext4 /dev/ram0
mount /dev/ram0 /ramdisk

rd_nr参数指定要创建的RAM磁盘数(默认情况下,它创建16个磁盘,即/dev/ram0通过/dev/ram15)。该rd_size参数的大小以千字节为单位。该$(( ... ))语法使您可以在Shell中进行算术运算。

要取消分配RAM磁盘,请卸载它并删除brd内核模块:

umount /ramdisk
modprobe -r brd

在内部创建块设备 ramfs

或者,您可以在以下内部创建块设备ramfs

mkdir /ramdisk-storage /ramdisk
mount -t ramfs ramfs /ramdisk-storage

truncate -s 4G /ramdisk-storage/ramdisk.img
mkfs.ext4 /ramdisk-storage/ramdisk.img
mount /ramdisk-storage/ramdisk.img /ramdisk

truncate命令将创建给定大小的空文件,以便按需初始化(即消耗内存)。

要取消分配RAM磁盘,请将其卸下并删除磁盘映像:

umount /ramdisk
rm /ramdisk-storage/ramdisk.img

tmpfs和比较ramfs

虽然tmpfsramfs比使用一个块设备更有效的,下面是它们的一些缺点的。

tmpfs可能会交换到磁盘。这样效率更高,但是有时您需要纯RAM磁盘:

  • 您正在使用的文件是敏感文件(例如,来自加密分区的文件)。
  • 您正在执行性能测试,并且您不希望磁盘I / O成为一个因素(SSD写入时间可能相差很大)。
  • 您正在解压缩一个大文件,并且不想用完SSD。

ramfs易于设置,删除文件后可回收空间,并更有效地使用RAM(系统不会缓冲文件,因为它知道文件位于RAM中)。但是它有自己的缺点和惊奇:

  • df实用程序不报告空间使用情况:

    root@cello-linux:~# df -h /ramdisk
    Filesystem      Size  Used Avail Use% Mounted on
    ramfs              0     0     0    - /ramdisk
    
  • 没有大小限制参数。如果将过多的内存放入ramdisk,系统将挂起。

  • 当您最不希望出现稀疏文件时,稀疏文件可能会变得稀疏。今天早上,我将VM映像(150G,但磁盘上使用了49G)复制到ramfs(我有128G的RAM)。那行得通。但是,当我复制ramfs到了目的地,我的系统变得反应迟钝。该cp实用程序显然在读取时填补了漏洞,但在写入时并未填补漏洞。

无论tmpfsramfs行为可能不同于真正的ext4文件系统。ext4避免在RAM中创建块设备并对其进行初始化。

要进行更深入的比较:https : //www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt


1

OP RAM的数量以MB表示。因此,您只需要输入16384就可以了。


1
不。“如果fs-size没有后缀,则将其解释为2的幂。” -男子mkfs.ext2
sourcejedi

1

您可以挂载ramfs文件系统,将项目复制到其中,然后从那里开始工作。这样可以确保您的输入文件已加载到RAM中,并且不会从速度较慢的磁盘驱动器中重新读取它们。但是,正如您发现的那样,这通常不是有用的策略。您已经获得了完全相同的收益。

Ramfs是一个非常简单的文件系统,可将Linux的磁盘缓存机制(页面缓存和dentry缓存)导出为可动态调整大小的基于RAM的文件系统。

- https://github.com/torvalds/linux/blob/v4.18/Documentation/filesystems/ramfs-rootfs-initramfs.txt

您已经可以相信,第一次读取输入文件时,它们会缓存在RAM中。您的输出文件也被缓存,因此您不必等待它们被写入磁盘。

对可以缓存的数量,缓存保持多长时间等没有人为的限制。只有在填满RAM后,缓存才会开始被丢弃。通过精心设计的算法来选择先删除哪个高速缓存。第一个近似值是我们将其描述为“最近最少使用”。请参阅Linux内核中用于OS文件缓存的页面替换算法是什么?

注意您的文本编辑器将显式fsync()保存文件到磁盘。

如果您运行涉及的程序的测试,则fsync()在像这样的文件系统中运行它们ramfs可能会加快它们的速度。另一种策略是尝试fsync()使用eatmydata/ 禁用nosync.so

其他一些操作系统可能有特定的限制,可以使用虚拟磁盘绕过这些限制。一方面,缺少任何文件缓存是ramdisk在DOS上流行的原因。

tmpfs

tmpfs与的工作方式相同ramfs,不同之处在于,如果有交换空间,它可以使用交换空间。也就是说,如果您需要RAM来做其他事情,最近使用最少的算法可能会从tmpfs中选择数据块并将其交换到磁盘。

大多数人坚持使用tmpfs,因为它还可以限制总大小,并显示正确使用的空间,例如在df命令中。我不确定为什么存在这种差异。大小限制tmpfs可以防止意外填充整个RAM并基本上杀死系统。它默认为您RAM的一半。

写入速度变慢的其他原因

上面是针对您的案例的简化。在您的情况下,对文件的写操作无需等待磁盘。但是,在某些情况下也会这样做。请参阅出色的博客文章为什么有时缓冲写入会停顿。最令人惊讶的情况是最近对Linux进行的一种更改,称为“稳定页写入”。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.