Redis高并发丢包主因是内核全连接队列溢出,需同步调大net.core.somaxconn、Redis tcp-backlog及systemd LimitNOFILE三者,并验证ss -lnt中Send-Q是否生效。

Redis集群在高并发下连接积压,不是Redis本身卡住,而是Linux内核全连接队列(accept queue)被撑爆了——net.core.somaxconn太小是主因,改它就能立竿见影。
为什么ss -lnt里Recv-Q持续非零?
这表示已完成三次握手、等待Redis调用accept()的连接正在排队。如果Recv-Q长期 > 0(比如稳定在 200~500),说明Redis主线程来不及处理新连接;如果接近Send-Q(比如 65530/65535),就是队列真满了。
-
Recv-Q不为零 ≠ Redis慢,可能是瞬间建连速度远超accept()频率(尤其压测时大量短连接) - Redis 6.0+ 虽支持IO线程,但
accept()仍在主线程,无法绕过这个瓶颈 -
netstat -s | grep "listen overflows"输出非零(如listen overflows: 17),就是铁证
必须同步改这三项,只调sysctl没用
单改net.core.somaxconn只是“纸上谈兵”,Redis进程根本拿不到这个上限。得三者齐备:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 内核参数:
sudo sysctl -w net.core.somaxconn=65535,并写入/etc/sysctl.d/99-redis.conf持久化 - Redis配置:
tcp-backlog 65535加到redis.conf(6.2+才支持;老版本需确认glibc是否自动提升,否则无效) - 进程限制:
LimitNOFILE=65536写进/etc/systemd/system/redis-server.service的[Service]段,再systemctl daemon-reload && systemctl restart redis-server
ss -lnt | grep :6379怎么看是否生效?
执行后看输出第三列(Send-Q)是否变成你设的值:
State Recv-Q Send-Q Local Address:Port Peer Address:Port LISTEN 0 65535 *:6379 *:*
如果还是128或511,说明:
- Redis没重启(配置未加载)
-
tcp-backlog没写对位置(必须在redis.conf全局段,不能在replicaof等子节里) - systemd服务没重载,
cat /proc/$(pgrep redis-server)/limits里Max open files仍是默认值
真正卡点不在Redis代码里,而在内核和启动环境的衔接处——哪怕tcp-backlog设成65535,LimitNOFILE还是1024,Redis照样只能打开1024个fd,队列再大也用不上。

















