您的位置:首页 > 理论基础 > 计算机网络

Redis repl-disable-tcp-nodelay配置

2014-03-20 19:14 429 查看
Base: Redis 2.8.7

Redis的Replication有一个配置“repl-disable-tcp-nodelay”,如下

# Disable TCP_NODELAY on the slave socket after SYNC?

#

# If you select "yes" Redis will use a smaller number of TCP packets and

# less bandwidth to send data to slaves. But this can add a delay for

# the data to appear on the slave side, up to 40 milliseconds with

# Linux kernels using a default configuration.

#

# If you select "no" the delay for data to appear on the slave side will

# be reduced but more bandwidth will be used for replication.

#

# By default we optimize for low latency, but in very high traffic conditions

# or when the master and slaves are many hops away, turning this to "yes" may

# be a good idea.

repl-disable-tcp-nodelay no

解释:

在slave和master同步后(发送psync/sync),后续的同步是否设置成TCP_NODELAY

假如设置成yes,则redis会合并小的TCP包从而节省带宽,但会增加同步延迟(40ms),造成master与slave数据不一致

假如设置成no,则redis master会立即发送同步数据,没有延迟

前者关注性能,后者关注一致性

代码分析:


命令配置,sync&psync都配置响应为syscCommand:

Redis.c

{"sync",syncCommand,1,"ars",0,NULL,0,0,0,0,0},

{"psync",syncCommand,3,"ars",0,NULL,0,0,0,0,0},

syscCommand函数:

Replication.c

void syncCommand(redisClient *c) {
     ......
    if (!strcasecmp(c->argv[0]->ptr,"psync")) {//增量同步
        if (masterTryPartialResynchronization(c) == REDIS_OK) {
            server.stat_sync_partial_ok++;
            return; /* No full resync needed, return. */
        } else {
            char *master_runid = c->argv[1]->ptr;
            if (master_runid[0] != '?') server.stat_sync_partial_err++;
        }
    } else {//全量同步
        c->flags |= REDIS_PRE_PSYNC;
    }

    /* Full resynchronization. */
    server.stat_sync_full++;

    /* check是否需要生成rdb文件*/
    if (server.rdb_child_pid != -1) {
        ......
    } else {
        //fork子进程生成RDB文件
        ......
    }

    //调用setsockopt设置TCP_NODELAY
    if (server.repl_disable_tcp_nodelay)
        anetDisableTcpNoDelay(NULL, c->fd); /* Non critical if it fails. */
    ......
}


TCP_NODELAY

TCP/IP协议发送数据过程:

1. 发送方发送数据

2. 接收方接收到数据后,回复ACK向发送者确认接收

为了尽可能利用网络带宽,TCP/IP使用了Nagle算法(一般服务器默认开启)

Nagle算法是为了避免网络上充斥着小数据包,其基本定义:任意时刻,最多只能有一个还没有接收到ACL确认的数据块。

具体规则如下:

IF 有新的数据要发送

IF 窗口大小> = MSS

立即发送

ELSE IF有未确认的数据仍然在等待

在接收缓冲区中的排队,直到一个应答

ELSE

立即发送

FI

FI

Nagle算法缓存了小数据包,提高了网络效率,但会单来一个不可预测延迟的问题。

但仅仅是Nagle算法并不会带来前文所说的40ms延迟的问题

A向B发送消息,B回馈ACK,A继续发送下一条,没有问题!

40ms是Nagle和TCP确认延迟机制共同作用的结果

TCP确认延迟机制:当Server端收到数据之后,它并不会马上向client端发送ACK,而是会将ACK的发送延迟一段时间,这个时间大概为40ms

A向B发送消息,B延迟40ms发送ACK(TCP确认延迟),由于B没有回复ACK,A不能发送下一条(Nagle),此时带来延迟

想深入理解Nagle和Tcp确认延迟的同学,推荐一篇非常好的文章,再探linux下的tcp延迟确认机制
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: