1

在我的应用程序中,我向服务器发送了两条小消息(类似 memcached 的服务)。在类似 Python 的伪代码中,这看起来像:

sock.send("add some-key 0")
ignored = sock.recv(...)
sock.send("incr some-key 1")
new_value = sock.recv(...)

由于服务器支持即发即弃式写入,我可以优化此代码,使其看起来更像:

sock.send("add some-key 0 noreply")
sock.send("incr some-key 1")
new_value = sock.recv(...)

然而,这需要更长的时间——这个版本的平均时间为 40 毫秒,而前一个版本的平均时间不到 1 毫秒。

此外,我注意到,如果我使用 来创建套接字TCP_NODELAY,从而禁用 Nagle 算法,则第二个片段的时间与第一个相似。这表明延迟发生在两个send()s 之间(“写-写-读”问题)。

我有理由相信禁用 Nagle 是我的应用程序的正确举措——我有相当多的相当小的写入必须以尽可能少的延迟进行处理——但我不知道为什么它不是在第一个例子中是必要的。是否recv()强制内核发送任何缓冲的写入?我怀疑这是真的,但我无法在任何地方找到这方面的文档。

(注意这是 Linux 2.6.32 和 glibc 2.12 以及 Python 2.6.8,以防其中任何一个对答案有任何影响)

4

1 回答 1

1

recv() 是否强制内核发送任何缓冲的写入?

不,TCP 连接的两个方向是完全独立的。

Nagle 算法在某些情况下延迟发送数据包最多 200 毫秒,以便它可以与后续写入合并。这就是您所看到的,当您禁用 Nagle 时,它​​会停止发生。

我怀疑这是真的

它不是。

但我无法在任何地方找到与此相关的文档。

你不会的。

于 2013-10-29T22:08:40.523 回答