在我的应用程序中,我向服务器发送了两条小消息(类似 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,以防其中任何一个对答案有任何影响)