如何避免物理磁盘I/O

3
我有一个进程在网络上写大量数据。假设它在A机器上运行,并通过NFS将大约70-80GB的文件倾倒到B机器上。在进程1完成并退出后,我的进程2在A机器上运行,并从B机器上的NFS获取此文件。整个周期中的瓶颈是写入和读取此巨大数据文件。如何减少I/O时间?我能否在进程1退出后以某种方式保持数据已加载到内存中,供进程2随时使用?
我希望能够得到这方面的建议。谢谢。
编辑:由于进程2直接从网络上“读取”数据,是否最好首先将数据复制到本地,然后从本地磁盘读取?我的意思是(网络读取时间)>(复制到本地磁盘)+(从本地磁盘读取)。

1
为什么不在A机器上保存文件? - Justin
2
你能直接将数据从进程1传输到进程2吗? - Sander De Dycker
6个回答

2
如果您想将数据保留在内存中,则需要70-80 GB的RAM。
最好的方法可能是将本地存储(硬盘驱动器)连接到A系统,以便将此文件保存在本地。

1
显而易见的答案是要减少网络写入 - 这似乎能够在指数级别上节省时间并提高可靠性 - 没有必要将 任何 文件复制到另一台计算机,然后再将其复制回来,因此为了更精确地回答您的问题,我们需要更多的信息。

1

这种方法存在大量的网络和IO开销,因此您可能无法进一步降低延迟。

  1. 由于文件超过80GB,因此创建一个mmap,处理1将写入,稍后处理2可以从中读取-不涉及网络,仅使用机器A-但仍然无法避免IO开销。
  2. 更快的方法:两个进程可以同时运行,并且您可以拥有信号量或其他信号机制,在其中进程1可以指示进程2准备好读取文件。
  3. 最快的方法:让进程1创建共享内存并与进程2共享。每当达到限制(基于RAM大小的最大数据块),让进程1向进程2发出信号,表示可以读取和处理数据-只有当文件/数据实际上可以逐块处理而不是一个80GB的大块时,此解决方案才可行。

共享内存大小有上限。我认为默认值是32MB。是否有办法通过我的应用程序来增加它? - user900563
您可以通过 ipcs -l 查看限制,并且可以通过 /etc/sysctl.conf 更改限制。设置 kernel.shmmax=<value> 并执行 sysctl -p。您只能以 root 身份执行此操作。虽然 _sysctl() 可以从应用程序中实现此操作,但使用此函数已被弃用。 - Arun

1

无论您使用mmap还是普通的read/write,都应该没有太大区别;无论哪种方式,所有操作都通过文件系统缓存/缓冲区进行。最大的问题在于NFS。唯一能使其高效的方法是将中间数据存储在机器A上,而不是将其全部发送到机器B上,然后立即再次拉回。


那是一个很好的观点。有没有一种安全的挂载方式可以用作本地存储?我可能没有在'cwd'中写入权限。 - user900563

0
  1. 您可以使用RAM磁盘作为存储设备
  2. NFS较慢。尝试使用其他方式传输数据到另一台PC。例如 - TCP/IP流。
  3. 另一个解决方案 - 您可以使用内存数据库(例如TimesTen)

0

使用tmpfs将内存用作(临时)文件。

使用mbuffernetcat,可以在不存储中间流的情况下简单地从一个端口转发到另一个端口,但仍允许以不同速度进行流式传输:

machine1:8001 -> machine2:8002 -> machine3:8003

在machine2上配置一个工作任务:

 netcat -l -p 8002 | mbuffer -m 2G | netcat machine3 8003

这将允许最多缓冲2GB的数据。如果缓冲区填满了100%,machine2将开始阻塞从machine1的读取,延迟输出流而不会失败。

当machine1完成传输时,第二个netcat将保持存在,直到mbuffer耗尽。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接