我们的服务器总 RAM 为 64GB,应用程序通常最多使用其中的 30GB 可用 RAM。其中一个应用程序处理大量平面文件,我们遇到了吞吐量问题,即等待磁盘 I/O。在探索可能的解决方案时,我提出了 RAM 磁盘的想法。RAM 磁盘的问题是其固有的波动性。
我找到了有关 RAM 磁盘、RAID 1 配置和逻辑镜像卷的单独文档,以便进行分组身体的磁盘,但我似乎找不到任何文档表明这些磁盘复制解决方案是否可以与 RAM 磁盘一起使用。更重要的是,由于这个想法是让 RAM 磁盘可用于读/写,并让物理磁盘“影子”RAM 磁盘,赶上写入,我们希望 RAM 磁盘成为所有读/写的“主”磁盘。
需要注意的是,我们会喜欢以避免仅使用 RAM 缓存操作系统中的文件,但如果我们可以获得与独立 RAM 磁盘相同的性能,那么这种方法是可行的。我们最初避免这样做,因为某些文件通常不会长时间被访问,但仍然需要按需读取/写入速度。
答案1
需要注意的是,我们希望避免仅使用 RAM 缓存操作系统中的文件,但如果我们可以获得与独立 RAM 磁盘相同的性能,那么这种方法是可行的。我们最初避免这样做是因为某些文件通常不会长时间被访问,但仍然需要按需读取/写入速度。
你可以使用vmtouch
解决你的问题。这是一个实用程序,它允许您将某些文件甚至整个目录及其下的所有内容固定在页面缓存中,这样它们就不会被逐出,即使它们长时间未被访问(这是您不完全依赖页面缓存的最初原因)。这最多需要与您的 RAM 磁盘相同的内存量,实际上甚至更少。您仍将使用页面缓存,但它将产生与使用 RAM 磁盘处理所有内容类似的性能(实际上性能更佳,因为不会涉及 MD 驱动程序)。
答案2
这可以被黑客入侵,但这是一个坏主意并且可能存在可靠性和可维护性方面的多个问题。
我认为 RAMdisk 和物理磁盘的 RAID1 会受限于物理磁盘的性能,因为 RAID1 功能的一部分是确保两个副本同步。
对于读取,可能会有一些好处,因为 MD 驱动程序可以在不同的设备之间分配读取。
创建此项的可能步骤:
- 创建一个空文件,其大小与你想要支持的数组大小相同
- 用于
losetup
从文件创建块设备。 - 使用
mdadm
新创建的块设备和相应的硬盘分区来创建阵列。 - 在新的 MD 阵列上创建文件系统。
我自己还没有尝试过,所以这只是一个关于如何做到这一点的理论例子。
答案3
首先,RAM 磁盘几乎绝不Linux 上的正确答案。因为它是一个块设备,所以任何读取都必须经过块层、文件系统和常规 VFS 层,和除了存储在 RAM 磁盘中之外,数据最终还会缓存在 RAM 中。这种数据复制以及所涉及的额外层数是 tmpfs 存在于 Linux 上的原因,tmpfs 文件系统不涉及块层,而是直接将数据存储在页面缓存中,从而跳过所有额外的复杂性。它还会根据存储在其中的数据量自动调整大小(而不必预先定义大小),甚至可以利用交换空间。如果您认为需要 ramdisk,那么 99% 的时间您实际上应该使用 tmpfs。
现在,就实际解决方案而言......
如果你的所有数据都能放在 RAM 中,那么最好将它们全部固定在 RAM 中,方法是使用类似虚拟触摸或者让应用程序 mmap 所有文件,然后在所有映射区域上调用 mlock。
如果您的数据不能全部装入 RAM,您有两个现实的选择:
- 将压缩后的数据存储在磁盘上,最好使用提供透明压缩的文件系统,例如 BTRFS、F2FS 或 ZFS。如果你有一个相当快的 CPU,这通常会减少读取大型文件所需的时间,但代价是需要更多 CPU 时间。改进通常与数据压缩程度成正比,但在许多情况下可以轻松转化为 30% 或更多的改进。
- 考虑投资更快的存储。要么足以替换现有存储,要么可以与缓存从功能上加速您现有的存储。
答案4
如果您需要持久性,RAMDISK 不是正确的解决方案。
我强烈建议投资一对快速(企业级,具有断电保护功能)NVMe 磁盘,放入经典的 RAID1(镜像)阵列。