背景
我正在尝试以全速(12.5GB/s)或接近全速将大约 150GB 下载到具有 100gbps 网络连接的新创建的 Linux 盒子(AWS EC2)。网络端运行良好。然而,尽管盒子有 192GB 的 RAM,但我很难在盒子上找到可以足够快地保存所有数据的任何地方。
到目前为止,我最成功的尝试是使用brd
内核模块分配足够大的 RAM 块设备,并并行写入该设备。当块设备已被完全写入时,这会以所需的速度(使用直接 io)工作,例如使用dd if=/dev/zero ...
不幸的是,当brd
设备新创建时,它只接受 2GB/s 左右的写入速率。
我的猜测是,这是因为brd
挂钩到“正常”内核管理的内存,因此当第一次使用每个新块时,内核必须实际分配它,其速度不超过 2GB/s。
到目前为止我所尝试的一切都存在同样的问题。看起来,、、、tmpfs
以及其他所有提供 RAM 存储挂钩到正常内核内存分配系统的东西ramfs
。brd
问题
Linux 有没有办法创建块设备真实的内存,而不经过正常内核的内存管理?
我在想也许有一个内核模块会在启动时分割出一定量的内存,将其视为磁盘。该内存不会被内核视为正常内存,因此将其用于其他用途不会有任何问题。
或者,是否有某种方法可以让内核brd
快速完全初始化 ramdisk(或类似的)?我尝试单独写入磁盘的最后一个块,但毫不奇怪,这没有帮助。
非 RAM 替代方案
理论上,NVMe SSD 的 RAID 可以达到所需的写入速度,尽管似乎可能存在某种阻碍如此高的整体 I/O 的瓶颈。我尝试将 RAID 0 与 8 个 NVMe SSD 一起使用mdadm
但没有成功,我认为部分原因是块大小方面的困难。要使用直接 io 并绕过内核缓存(这似乎是必要的),唯一可以使用的块大小是 4096,这显然太小而无法有效利用 SSD 本身。这里的任何替代方案将不胜感激。
评论
我知道 2GB/s 听起来很多,而且下载这些数据只需要几分钟,但我需要在不到一分钟的时间内从根本没有 EC2 实例到加载 150GB 的 EC2 实例。从理论上讲,这应该是完全可能的:网络堆栈和物理 RAM 完全能够如此快速地传输数据。
谢谢!
答案1
在 tmpfs 文件系统上,通过并行运行 64 个作业,我可以在 7.8 秒内复制 64 个 1.6 GB 的文件(总共 100GB)。这非常接近 100 Gbit/s。
因此,如果您并行运行它(元代码):
curl byte 1G..2G | write_to file.out position 1G..2G
ẁrite_to
可以用 来实现mmap
。
也许您可以简单地写入不同的文件,使用循环设备,并以线性模式使用 RAID: https://raid.wiki.kernel.org/index.php/RAID_setup#Linear_mode
如果您控制两端,则将源设置为 150 个 1 GB 文件,用作循环设备和线性模式的 RAID。然后您应该并行复制这些并再次设置线性 RAID。