一次将 GB 字节写入 TCP 套接字是否是一种好习惯?
Is it a good practice to write a GB of byes into a TCP socket in one go?
我正在维护一些成熟的生产代码,这些代码通过 TCP 套接字发送数据。它总是将大块数据分成许多数据包,每个数据包 1000 字节。我只是想知道为什么这样做。为什么我不能一次性将 1 GB 的字节数组写入套接字?这样做有什么缺点?
根据底层实现,尝试批量发送 1GB 可能会导致 1GB 被复制到某个缓存中,然后在那里保留一段时间。因此,如果没有足够的可用内存(即使有足够的可用内存 - 它可能不是使用它的最有效方式)也可能是个问题。
虽然“手动”将其分成 1000 字节的片段,但对我来说听起来有点矫枉过正。
有很多理由不立即投入一大块。
首先:即使在非常快的网络上发送 1 GB 的数据也会花费大量的时间。在 10Gbps 网络上,这将花费不到 1 秒的时间,这在计算机语言中是很长的时间。并且假设这个操作拥有可用的所有网络带宽,并且不必与其他任何东西共享。
这意味着如果您成功地对 TCP 套接字执行了 1GB write
调用,则需要一些时间才能实际发送后面的数据位。
同时,您必须将所有数据保存在内存中。这意味着您需要为整个交易分配并保留 1GB 的数据。
如果您改为填充一个小缓冲区并在每次写入之前从源读取(或生成,具体取决于数据的来源),那么您只需要一点内存(缓冲区的大小).
所有这些对于今天的机器来说可能听起来没什么大不了的,但考虑到许多服务器将同时服务数百台 clients/requests,如果每个服务器都需要 1GB 的缓冲区,那么它可以增长到手快。
1000 是否适合该缓冲区?我不是网络专家,但我怀疑这有点低。也许大约 64k 的大小是合适的,但其他人可以在此处提供更详细的信息。找到合适的缓冲区大小有时会有点棘手。
我正在维护一些成熟的生产代码,这些代码通过 TCP 套接字发送数据。它总是将大块数据分成许多数据包,每个数据包 1000 字节。我只是想知道为什么这样做。为什么我不能一次性将 1 GB 的字节数组写入套接字?这样做有什么缺点?
根据底层实现,尝试批量发送 1GB 可能会导致 1GB 被复制到某个缓存中,然后在那里保留一段时间。因此,如果没有足够的可用内存(即使有足够的可用内存 - 它可能不是使用它的最有效方式)也可能是个问题。
虽然“手动”将其分成 1000 字节的片段,但对我来说听起来有点矫枉过正。
有很多理由不立即投入一大块。
首先:即使在非常快的网络上发送 1 GB 的数据也会花费大量的时间。在 10Gbps 网络上,这将花费不到 1 秒的时间,这在计算机语言中是很长的时间。并且假设这个操作拥有可用的所有网络带宽,并且不必与其他任何东西共享。
这意味着如果您成功地对 TCP 套接字执行了 1GB write
调用,则需要一些时间才能实际发送后面的数据位。
同时,您必须将所有数据保存在内存中。这意味着您需要为整个交易分配并保留 1GB 的数据。
如果您改为填充一个小缓冲区并在每次写入之前从源读取(或生成,具体取决于数据的来源),那么您只需要一点内存(缓冲区的大小).
所有这些对于今天的机器来说可能听起来没什么大不了的,但考虑到许多服务器将同时服务数百台 clients/requests,如果每个服务器都需要 1GB 的缓冲区,那么它可以增长到手快。
1000 是否适合该缓冲区?我不是网络专家,但我怀疑这有点低。也许大约 64k 的大小是合适的,但其他人可以在此处提供更详细的信息。找到合适的缓冲区大小有时会有点棘手。