在我的应用程序中,我向服务器发送了两条小消息(类似于memcached的服务)。在类似Python的伪代码中,这看起来像:
sock.send("add some-key 0")
ignored = sock.recv(...)
sock.send("incr some-key 1")
new_value = sock.recv(...)
由于服务器支持fire-and-forget-style写入,我可以优化此代码看起来更像:
sock.send("add some-key 0 noreply")
sock.send("incr some-key 1")
new_value = sock.recv(...)
然而,这需要更长的时间 - 这个版本的平均时间为40毫秒,而前者平均不到1毫秒。
此外,我注意到如果我使用TCP_NODELAY
创建套接字,从而禁用Nagle的算法,则第二个代码段的时序与第一个类似。这表明延迟发生在两个send()
之间(“写 - 写 - 读”问题)。
我有理由相信,禁用Nagle是我的应用程序的正确举措 - 我有相当大的相当小的写入量,必须以尽可能小的延迟处理 - 但我不知道为什么它在第一个例子中没有必要。 recv()
强制内核发送任何缓冲写入吗?我怀疑这是真的,但我无法在任何地方找到相应的文档。
(注意这是Linux 2.6.32和带有Python 2.6.8的glibc 2.12,如果其中任何一个与答案有关)
答案 0 :(得分:1)
recv()强制内核发送任何缓冲的写入吗?
没有。 TCP连接的两个方向完全独立。
Nagle算法在某些情况下延迟发送数据包最多200毫秒,以便它可以与后续写入合并。这就是你所看到的,当你禁用Nagle时它就会停止发生。
我怀疑这是真的
不是。
但我无法在任何地方找到相应的文档。
你不会。