Redis的tcp-backlog配置不生效是因为受内核参数net.core.somaxconn限制,实际生效值为二者最小值;需同步调整内核参数、redis.conf及ulimit才能解决。

redis.conf 里的 tcp-backlog 不生效?先看内核限制
Redis 的 tcp-backlog 配置不会自动突破内核上限,它只是告诉 Redis 在调用 listen() 时传什么值;真正起作用的是内核参数 net.core.somaxconn。如果后者是默认的 128,哪怕你在 redis.conf 里写 tcp-backlog 65535,Redis 启动时也会默默截断为 128,并在日志里打 warning(搜 WARNING: The TCP backlog setting 就能确认)。
验证方法:
– 查内核值:cat /proc/sys/net/core/somaxconn
– 查 Redis 实际监听队列长度:ss -lnt | grep :6379,看 Send-Q 列是否等于你设的值
– 查溢出统计:netstat -s | grep -i "listen overflows",非零说明已丢连接
必须同步改三个地方,缺一不可
只改 redis.conf 或只改 sysctl,都会白忙活。要让高并发建连不丢包,得同时满足:
- 内核层:
net.core.somaxconn调大(建议 4096 或 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()失败会直接报错
为什么压测时 Connection refused 却抓不到 RST?
这不是网络设备问题,也不是 Redis 拒绝连接,而是内核在全连接队列满后静默丢弃已完成三次握手的连接——不发 RST,也不重传 SYN-ACK,客户端只能等超时。这种“丢包”在 tcpdump 里看不到对应包,netstat -s 却显示 listen overflows,就是典型症状。
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
根本原因是 Redis 单线程 accept() 速度跟不上建连洪峰,尤其当客户端短连接频繁重建、或有慢客户端占着连接不发命令时,队列堆积更快。epoll 本身没问题,瓶颈卡在主线程处理连接的速度。
别忽略 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 - 检查
ss -lnt输出是否真有你期望的地址+端口组合
这个细节在集群多节点或容器环境下特别容易被绕过去,结果调了半天 tcp-backlog,发现压根没压到那个监听端口上。

















