redis性能慢多因内核参数未调优:必须将net.core.somaxconn与redis tcp-backlog均设为65535并验证生效,同步配置client-output-buffer-limit replica、vm.overcommit_memory=1、禁用透明大页及启用tcp_tw_reuse。

Redis在Linux上跑得慢,十有八九不是Redis配置问题,而是内核参数没调对。直接改/etc/sysctl.conf,配合sysctl -p生效,就能解决连接拒绝、缓冲区溢出、内存分配失败等典型卡点。
net.core.somaxconn 与 tcp-backlog 必须对齐
这是高并发下连接被拒绝(Connection refused)的头号原因。Redis的tcp-backlog值必须 ≤ 系统net.core.somaxconn,否则多余连接直接丢弃。
-
net.core.somaxconn是内核级全连接队列上限,建议设为65535 - Redis配置中
tcp-backlog也设为65535,不能更大 - 若用Docker,需在
docker run加--sysctl net.core.somaxconn=65535,容器内默认继承宿主机值但可能被限制
client-output-buffer-limit 不调大,主从同步必断
主节点向从节点传输RDB或AOF时,如果从节点处理慢,数据会堆积在主节点输出缓冲区。默认限制太小,一压就触发replica buffer overflow,强制断连。
Linux 性能分析与调优专家,覆盖 CPU、内存、磁盘 I/O、网络、内核参数、编译优化、容器/K8s。适用场景:系统卡顿/高负载、内存不足/OOM/Swap 高、CPU 异常/iowait 高。
- 普通客户端缓冲区可保持默认,但
replica项必须放大:client-output-buffer-limit replica 1073741824 536870912 60(硬限1G,软限512M/60s) - 该值要大于最大RDB文件体积,否则同步中途就会被kill
- 搭配
repl-backlog-size一起调,避免从节点重连后无法部分同步
vm.overcommit_memory=1 是 fork 安全线
Redis持久化(RDB)、主从复制、AOF重写都依赖fork()子进程。若vm.overcommit_memory=0(默认),内核会按物理内存+swap预估是否允许分配,而Redis内存使用量常远超物理内存,导致fork()失败,日志里出现Can't save in background: fork: Cannot allocate memory。
- 必须设为
1:允许内核“先承诺后兑现”,只要地址空间够就放行 - 同时禁用透明大页:
echo never > /sys/kernel/mm/transparent_hugepage/enabled,否则fork()延迟飙升 - 该设置需写入
/etc/sysctl.conf并sysctl -p,重启后仍有效
TIME_WAIT 多且短连接频繁?开 tcp_tw_reuse
客户端频繁新建/关闭连接(如微服务间调用),大量TIME_WAIT socket 占满端口,报错Cannot assign requested address。
-
net.ipv4.tcp_tw_reuse = 1允许复用处于TIME_WAIT状态的socket,前提是时间戳开启(net.ipv4.tcp_timestamps = 1,通常默认开启) -
net.ipv4.tcp_fin_timeout = 30缩短FIN等待时间,加快回收 - 注意:
tcp_tw_recycle已废弃且在NAT环境下会导致连接异常,别用
真正容易被忽略的是:这些参数改完后,必须验证是否生效。比如sysctl net.core.somaxconn看输出值,redis-cli config get tcp-backlog确认Redis已加载,再用ss -lnt查监听套接字的Send-Q是否达到预期值——光写配置不验证,等于没调。










