Lew*_*ton 5 storage download file-transfer
如果我将文件直接下载到写入速度远低于互联网连接下载速度的设备,该怎么办?
写入挂起的数据是否移动到缓冲区或临时存储中?
这种行为是否取决于操作系统或浏览器或其他什么?
如果出现问题,我能做些什么来防止它发生?
在某种程度上,发生的情况取决于操作系统和应用程序。然而,人们可以做出以下一系列预测:
\n首先,堆栈的接收窗口将填满,其速度略低于网络的完整数据速率。由于TCP 慢启动算法和 TCP/IP 堆栈行为方式的其他影响,它的填充速度比网络的线路速率慢。
\n在我的 Linux 机器上,TCP 窗口可达 128 KiB(少于 1 个字节)。(比如说sysctl net.core.rmem_max获取你的盒子的价值。)但是,它通常小于这个最大值。我的盒子上的默认值为 4 KiB。(说sysctl net.ipv4.tcp_rmem要获得该值。)
您的应用程序将有自己的一些缓冲。它可能只有 1 个字节,但不能为零。Linux 需要一个零拷贝系统调用recvfile()来避免应用程序缓冲的需要,但它缺乏这一点。
缓冲区大小完全取决于应用程序员。在我编写的程序中,我使用了从大约十几个字节到最高 64 KiB 的任何位置,具体取决于应用程序的需求。通过观察其他应用程序的行为方式,我推断出在其他应用程序中使用了更大的缓冲区 (\xe2\x88\xbc1 MiB)。
\n应用程序几乎肯定会使用某种缓冲 I/O 机制来写入文件,例如C的stdio。这通常至少为 1 KiB,也可能为几个 KiB。在我的盒子上,它似乎默认为 8 KiB。
\n应用程序可能正在使用无缓冲的 I/O 或不断地将 I/O 缓冲区刷新到磁盘,但这并不常见。
\n存储设备的设备驱动程序可能有一些缓冲。它可能不多,但 4 KiB 的单页缓冲区也不是不合理的。
\n存储设备本身几乎肯定有一些缓存。例如,现代硬盘驱动器的缓存大小约为几十兆字节。如果您正在写入 RAID 设备,则可能还有更大的回写缓存。
\n所有这五个缓冲区都必须填满,底层存储设备的原始 I/O 性能才会产生任何影响。因为它们可以轻松地添加到 100 MiB 或更多,所以如果您想确保不只是测试这些缓冲区的组合行为,则需要使用大于此大小的传输大小进行测试。
\n介绍完所有这些后,我将回答您的顶级问题:只要您使用具有流量控制机制的网络协议 \xe2\x80\x94 例如TCP \xe2\x80\x94 就不应该有您提出的场景导致的问题。但是,如果您使用不可靠的网络协议(例如UDP ),并且构建在其之上的应用程序协议不提供自己的流量控制机制,则在这种情况下应用程序可能会被迫丢弃数据包。
\n