tcp-backlog不生效是因为受内核net.core.somaxconn限制,实际生效值为二者最小值;必须同步调大somaxconn、配置redis.conf中tcp-backlog并设置ulimit -n,三者缺一不可。

tcp-backlog 配置为什么总是不生效
Redis 的 tcp-backlog 值不会直接生效,它只是告诉 Redis 在调用 listen() 时传入的 backlog 参数;真正起作用的是内核参数 net.core.somaxconn。如果后者是默认的 128,哪怕你在 redis.conf 里写 tcp-backlog 65535,Redis 启动时也会默默截断为 128,并在日志里输出 WARNING: The TCP backlog setting of 65535 was truncated to 128。
- 查当前内核值:
cat /proc/sys/net/core/somaxconn - 查 Redis 实际监听队列长度:
ss -lnt | grep :6379,看Send-Q列是否等于你设的值 - 查丢连接证据:
netstat -s | grep -i "listen overflows",非零说明已有连接被静默丢弃
必须同步改齐的三个地方
只改 redis.conf 或只改 sysctl,都会白忙活。要让高并发建连不丢包,得同时满足:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 内核层:
net.core.somaxconn调大(建议 65535),临时生效:sysctl -w net.core.somaxconn=65535;持久化写入/etc/sysctl.d/99-redis.conf - Redis 层:6.2+ 版本在
redis.conf中加tcp-backlog 65535;老版本需确认 glibc 是否支持自动提升,否则可能卡死在 511 - 进程层:
ulimit -n要 ≥ 连接数上限(比如设成 100000),否则accept()失败会直接报错Too many open files
压测时 Connection refused 却抓不到 RST 怎么办
这不是 Redis 拒绝连接,而是内核在全连接队列满后静默丢弃已完成三次握手的连接——不发 RST,也不重传 SYN-ACK,客户端只能等超时。这种“丢包”在 tcpdump 里看不到对应包,netstat -s 却显示 listen overflows,就是典型症状。
- 根本原因是 Redis 单线程
accept()速度跟不上建连洪峰,尤其短连接频繁重建、或有慢客户端占着连接不发命令时,队列堆积更快 - 别指望调大
tcp-backlog就能解决一切——它只是缓解排队,不是加速处理;真瓶颈在主线程处理连接的速度 - epoll 本身没问题,问题出在事件循环里
accept()的吞吐能力,以及后续read()和 client 初始化开销
bind 地址和压测路径不一致导致调优失效
如果你 Redis 配了 bind 127.0.0.1,但压测走的是 localhost 或域名解析,glibc 可能走 IPv6 回环(::1),导致实际监听的是两个不同 socket,tcp-backlog 设置对 IPv6 socket 无效。
- 最稳妥做法:统一用
bind 0.0.0.0+protected-mode no(测试环境),或明确指定bind 127.0.0.1 ::1 - 确保压测命令直连 IP,比如
redis-cli -h 127.0.0.1 -p 6379,而不是-h localhost - 检查
ss -lnt输出是否真有你期望的地址+端口组合,否则所有调优都压错了监听实例
tcp-backlog 就只是配置文件里一行安静的数字。










