首页/数据/Redis 进阶速查/TCP_NODELAY 与 Nagle 延迟
性能与排障129 条

TCP_NODELAY 与 Nagle 延迟

客户端小包连续写可能触发 Nagle 与延迟确认交互,追加约 40ms 量级延迟;多数客户端库默认开启 TCP_NODELAY,自研客户端应显式设置。

Redis 进阶速查数据更新于 2026-10-13

小包延迟从哪来

客户端连续写小包时可能触发 Nagle 算法与延迟确认的交互:发送方等待前一个小包被确认才发下一个,接收方又延迟确认等待能否凑批,两者叠加会给交互加上数十毫秒量级的等待,表现出来像随机出现的固定延迟。多数成熟客户端库默认开启 TCP_NODELAY 规避这一点,自研客户端需要显式设置该 socket 选项。

基本信息

触发场景小包连续写叠加对端延迟确认
典型表现数十毫秒量级的附加延迟,看似随机
解决方式客户端 socket 设置 TCP_NODELAY
服务端侧服务端连接通常已按优化方式配置,问题多出在客户端
验证方式对比开关该选项前后的延迟分位

典型使用场景

  • 自研客户端:直接操作 socket 时容易漏掉这个选项
  • 延迟毛刺排查:出现固定量级毛刺时先排除这一项
  • 小命令高频调用:小包占比高时更明显
  • 客户端库升级:确认默认选项在新版本中仍按预期生效
  • 多语言栈混用:不同语言库的默认行为不一致,需要逐一确认

验证与排查

验证与排查
# 客户端 socket 选项示意(以所用语言与库为准)
# setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, 1)
redis-cli --latency-history -i 5            # 看延迟时间序列,而不是单次结果
redis-cli INFO latencystats                 # 服务端侧分命令延迟分位
redis-cli INFO commandstats | grep usec_per_call   # 单命令平均耗时
redis-cli SLOWLOG GET 10                    # 排除服务端慢命令造成的排队

判断线索

现象可能原因下一步
固定量级毛刺小包与延迟确认交互确认客户端选项是否设置生效
延迟随时段波动对端排队或负载升高查慢日志与服务端命令耗时
只有部分客户端慢客户端实现差异对比不同语言库的默认设置
只有批量调用慢单次命令过大拆分批次,而不是继续调 socket 选项
服务端侧连接一般已做过这层优化,看到延迟毛刺先确认客户端类型与库版本,问题多出在自研实现上。
把所有小包延迟都归因于 Nagle 会漏掉真正的排队:先看命令耗时分布与慢日志,再判断是否属于客户端实现问题。

易错点

  • 自研客户端未设置该选项:出现固定量级延迟且难以定位,排查成本远高于一行配置
  • 只凭平均延迟判断:毛刺被平均值抹平,需要看分位或时间序列
  • 改完不做前后对比:无法确认改善是否真的来自这次改动
  • 忽略其他排队来源:服务端慢命令与链路问题也会产生相似表现

数据来源与参考

  • Redis 官方实践:网络选项
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌