Redis repl-disable-tcp-nodelay配置

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

  1. void syncCommand(redisClient *c) {  
  2.      ......  
  3.     if (!strcasecmp(c->argv[0]->ptr,"psync")) {//增量同步  
  4.         if (masterTryPartialResynchronization(c) == REDIS_OK) {  
  5.             server.stat_sync_partial_ok++;  
  6.             return; /* No full resync needed, return. */  
  7.         } else {  
  8.             char *master_runid = c->argv[1]->ptr;  
  9.             if (master_runid[0] != '?') server.stat_sync_partial_err++;  
  10.         }  
  11.     } else {//全量同步  
  12.         c->flags |= REDIS_PRE_PSYNC;  
  13.     }  
  14.   
  15.     /* Full resynchronization. */  
  16.     server.stat_sync_full++;  
  17.   
  18.     /* check是否需要生成rdb文件*/  
  19.     if (server.rdb_child_pid != -1) {  
  20.         ......  
  21.     } else {  
  22.         //fork子进程生成RDB文件  
  23.         ......  
  24.     }  
  25.   
  26.     //调用setsockopt设置TCP_NODELAY  
  27.     if (server.repl_disable_tcp_nodelay)  
  28.         anetDisableTcpNoDelay(NULL, c->fd); /* Non critical if it fails. */  
  29.     ......  
  30. }  

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延迟确认机制

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值