tcp_nodelay memcached java_spymemcached 的 useNagle 问题与 TCP/IP延迟发送数据

先说一下结论。

那么默认 spymemcached 是不启用 Nagle 算法的。

所以默认情况下不会引发恨少在《libmemcached的MEMCACHED_MAX_BUFFER问题》一文中提及的“shell脚本set 1000次8KB的item,只要3s左右,平均需要3ms。而C++版本则需要39s左右,平均耗时39ms……发现8KB的数据需要发送两次,两次write都是非常快的,但是等memcached返回时用了很多时间,主要的时间就耗费在这个地方”现象。咱们业务中心可以排除这个嫌疑。

什么是 Nagle 算法?

TCP/IP协议中,无论发送多少数据,总是要在数据前面加上协议头,同时,对方接收到数据,也需要发送ACK表示确认。为了尽可能地利用网络带宽,TCP总是希望尽可能地发送足够大的数据。(一个连接会设置MSS参数,因此,TCP/IP希望每次都能够以MSS尺寸的数据块来发送数据)。Nagle算法就是为了尽可能发送大块数据,避免网络中充斥着许多小数据块。

Nagle算法的基本定义是任意时刻,最多只能有一个未被确认的小段。 所谓“小段”,指的是小于MSS尺寸的数据块,所谓“未被确认”,是指一个数据块发送出去后,没有收到对方发送的ACK确认该数据已收到。

Nagle算法的规则(可参考tcp_output.c文件里tcp_nagle_check函数注释):

(1)如果包长度达到MSS,则允许发送;

(2)如果该包含有FIN,则允许发送;

(3)设置了TCP_NODELAY选项,则允许发送;

(4)未设置TCP_CORK选项时,若所有发出去的小数据包(包长度小于MSS)均被确认,则允许发送;

(5)上述条件都未满足,但发生了超时(一般为200ms),则立即发送。

spymemcached 默认不启用 Nagle 算法

/net/spy/memcached/ConnectionFactoryBuilder.java 中定义如下:

/**

* Builder for more easily configuring a ConnectionFactory.

*/

public class ConnectionFactoryBuilder {

protected boolean useNagle = false;

……

public ConnectionFactoryBuilder(ConnectionFactory cf) {

……

setUseNagleAlgorithm(cf.useNagleAlgorithm());

}

/**

* Set to true if you'd like to enable the Nagle algorithm.

*/

public ConnectionFactoryBuilder setUseNagleAlgorithm(boolean to) {

useNagle = to;

return this;

}

然后,转到 MemcachedConnection.java,说到底还是调用 socket 的 setTcpNoDelay 方法:

protected List createConnections(

……

ch.socket().setTcpNoDelay(!this.connectionFactory.useNagleAlgorithm());

通过 bean definition 可设置 useNagleAlgorithm

参考SpringIntegration文档,spring 里配置如下:

……

p.s.:

1)另一个常用的 memcached java client——xmemcached 从1.3.6版本开始也默认禁用了 Nagle 算法。

2)mongo-java-driver默认也禁用Nagle算法(DBPort.java 63行)。

参考资源:

3)2009, Issue 88:  Turn off TCP nagle can hugely improve performance;

1)55最佳实践系列:MongoDB最佳实践(2012-12-15 15:48)

2)55最佳实践系列:Logging最佳实践(2012-12-15 16:43)

3)最佳实践系列:前端代码标准和最佳实践(2012-12-19 23:33)

f753a58abfdfdf38b4f23dff65b1c6dc.png

7b7aaff89f862e603035e59af8fe3c11.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值