![需要一个高效的数据容器。尽快从存储移动到内存](https://linux22.com/image/612699/%E9%9C%80%E8%A6%81%E4%B8%80%E4%B8%AA%E9%AB%98%E6%95%88%E7%9A%84%E6%95%B0%E6%8D%AE%E5%AE%B9%E5%99%A8%E3%80%82%E5%B0%BD%E5%BF%AB%E4%BB%8E%E5%AD%98%E5%82%A8%E7%A7%BB%E5%8A%A8%E5%88%B0%E5%86%85%E5%AD%98.png)
问题:我需要尽快将大量数据从远程位置复制到系统内存中。
设想:我有一个数据处理系统。该系统是通过 shell 脚本即时构建的,使用从远程位置拉入的多个组件。
其中一个组件是作为文件组存储的大量数据块。
我的要求是从远程位置检索大量数据并尽快将其安装到系统内存中。这是一项要求,以便依赖此数据的系统可以在启动后尽快开始使用它进行处理。
问题:“什么是对我的数据最有效的容器?”
已尝试/考虑的解决方案:
- ISO 文件:需要非原生工具来创建和读取
- TAR 文件:提取可能需要很长时间
- 远程文件系统挂载为本地:速度很慢,因为需要将内容复制到内存中
- LVM 快照:更适合备份,不适用于恢复速度
笔记:
- 数据丢失并不是主要问题。
- 远程文件传输过程不是主要关注点,因为我已经有了足够的工具。
- 系统目前采用的是Ubuntu Linux。
答案1
“远程文件传输过程并不是我主要关心的问题,因为我已经有了足够的工具。”
如果您已经传输了文件,我建议使用 mmap(2)。
答案2
您应该考虑使用包含数据的文件系统的映像文件(将循环设备放在文件上losetup
并安装循环设备)。最快的方法可能是压缩的只读文件系统,如 squashfs。
如果不是同时需要所有数据,这甚至可以允许一些技巧。除了安装循环设备外,您还可以将 DM 设备放在其顶部,使用映像文件安装网络文件系统(或网络块设备),将第二个循环设备放在文件的网络版本顶部,然后将两个循环设备与 DM 设备组合在一起。
假设您必须复制 500 MiB 的数据。您开始复制它。一旦传输了前 100 MiB,您就会创建循环设备和 DM 设备。DM 设备指向本地文件的循环设备(用于前 100 MiB),指向另一个循环设备(用于其余部分)。例如,在每次传输 10 MiB 块之后,您都会暂停 DM 设备并重新加载它,边界会再移动 10 MiB。
风险在于:如果访问网络版本,则数据将被传输两次。因此,如果这种情况经常发生,则数据传输将花费更长时间(但整个过程可能会更早完成,具体取决于其访问特性)。
编辑1:
请参阅我在另一个问题下的回答解释如何以这种方式使用 DM 设备(但无需暂停/重新加载/恢复)。
答案3
我对 ISO 集装箱的初步研究显然是不完整的。ISO 集装箱似乎是最高效的,因为它能够快速找到内容。这是基于我的研究发现的,当然可能会发生变化。
通过 ISO 进行打包,我可以:
- 远程存储数据
- 通过多部分传输快速检索
- 将其存储在本地,直接存储在内存中
- 快速安装
使用这个容器,我能够将整个过程缩短到 1 分钟以内,这对于该项目来说是一个可以接受的容忍水平。
在 Ubuntu 中可以轻松创建此容器,使用类似以下命令:
mkisofs -o /tmp/data.iso /opt/data/
**请注意,这需要genisoimage
通过 轻松安装apt-get
。
为了将文件直接存储到内存中,我在/tmp
文件系统中创建了一个 ramdisk:
mount -t tmpfs -o size=3G tmpfs /tmp/data
使用多部分传输实用程序可以相对快速地检索容器。我使用了一个axel
以如下方式调用的实用程序:
axel -a -n 128 -o /tmp/data/data.iso https://s3.amazonaws.com/bucket/data.iso
最后我们将文件挂载到本地文件系统:
mount -o loop -r /tmp/data/data.iso /opt/data/
安装过程几乎是即时的,这使得系统可以快速开始使用数据进行处理。