CentOS环境下Redis服务器偶发不响应SYN包问题排查请求
兄弟,你这碰到的是Redis连接偶尔掉链子的TCP层问题——客户端发了SYN却收不到响应,卡在SYN_SENT状态,这种情况我之前排查过不少,大概率是服务器端的TCP队列、Redis自身阻塞或者系统配置的锅,给你梳理几个靠谱的排查方向:
排查步骤与解决方案
1. 先查TCP监听队列是否溢出(最常见原因)
当Redis的TCP监听队列被塞满时,新的SYN包会直接被服务器丢弃,根本不会返回SYN-ACK。你可以这么验证:
- 查看6379端口的监听队列状态:
重点看ss -ltnp | grep 6379Send-Q列,如果它等于Recv-Q的最大值(默认是Redis配置的tcp-backlog,一般是511),说明队列已经满了。 - 查看系统是否有丢弃SYN的统计:
如果这个数值一直在涨,那实锤就是队列溢出导致的。netstat -s | grep "SYNs to LISTEN sockets dropped"
解决办法:
- 修改Redis配置文件
redis.conf,把tcp-backlog调大(比如改成1024),然后重启Redis。 - 同时调整系统内核参数,确保队列上限足够:
echo "net.core.somaxconn = 2048" >> /etc/sysctl.conf echo "net.ipv4.tcp_max_syn_backlog = 2048" >> /etc/sysctl.conf sysctl -p
2. 检查Redis是不是被阻塞了
Redis是单线程的,如果它在处理慢查询、大键全量操作(比如KEYS *)或者RDB/AOF持久化的时候,主线程会被卡住,根本没时间处理新的连接请求。
排查方法:
- 看看慢查询日志里有没有耗时很长的命令:
redis-cli CONFIG GET slowlog-log-slower-than redis-cli SLOWLOG GET 10 - 检查持久化状态,看看是不是持久化过程拖慢了Redis:
关注redis-cli INFO persistencerdb_last_bgsave_time_sec或者aof_last_bgrewrite_time_sec,如果数值很大(比如几十秒),说明持久化阻塞了主线程。
解决办法:
- 把慢查询优化掉,比如用
SCAN代替KEYS,避免一次性操作大键。 - 调整持久化策略,比如在低峰期触发RDB备份,或者把AOF的同步频率调得宽松一点。
3. 排查防火墙是不是误杀了SYN包
有时候防火墙的自定义规则或者连接数限制,会把正常的SYN包给丢了。
排查方法:
- 看看iptables里有没有针对6379端口的DROP/REJECT规则:
也注意下有没有iptables -L -n -v | grep 6379--connlimit这类连接数限制规则。 - 临时关掉防火墙测试一下:
如果关掉后问题消失,那就是防火墙的锅。systemctl stop firewalld # 或者用iptables -F清空规则
解决办法:
- 调整防火墙规则,允许6379端口的正常TCP连接,或者取消不合理的连接数限制。
4. 检查服务器资源是不是被耗尽了
如果服务器的CPU、内存或者网络带宽被其他进程占满了,Redis也没法处理新的连接请求。
排查方法:
- 实时监控系统资源:
重点看CPU使用率、内存占用,还有topwa(IO等待)指标,如果wa很高,说明磁盘IO拖慢了系统。 - 查看网络带宽是否饱和:
sar -n DEV 1
解决办法:
- 如果是资源不够,要么升级服务器配置,要么把其他占资源的进程优化掉,给Redis留出足够的资源。
5. 补全tcpdump的捕获内容
你提供的tcpdump内容不完整,建议完整捕获一次失败的连接过程,确认服务器确实没发SYN-ACK,而不是捕获工具漏了。用这个命令抓包:
tcpdump -i any host 192.168.1.110 and port 6379 -w syn_fail.pcap
之后用Wireshark打开这个pcap文件,确认服务器端到底有没有收到SYN包,以及有没有发出SYN-ACK。
内容的提问来源于stack exchange,提问作者bobunderson
相关产品推荐
相关产品推荐

