内核建连队列与 somaxconn
新建连接在完成三次握手前要进入内核的排队队列:已完成握手等待应用 accept 的全连接队列受 net.core.somaxconn 约束,半连接队列受 net.ipv4.tcp_max_syn_backlog 约束。这两个值偏小时,高并发建连会出现连接被丢弃或客户端超时重试。Redis 侧的 tcp-backlog 只是它向内核申请的 accept 队列长度,如果这个值大于内核 somaxconn,实际生效值会被内核压到 somaxconn,Redis 启动日志里通常会有提示。
基本信息
| 内核参数一 | net.core.somaxconn |
|---|---|
| 内核参数二 | net.ipv4.tcp_max_syn_backlog |
| Redis 侧 | tcp-backlog(默认 511) |
| 查看方式 | sysctl 参数名 或 sysctl -a |
| 持久化位置 | /etc/sysctl.d/ 下的配置文件 |
| 修改权限 | root |
| 生效日志 | Redis 启动时的 backlog 相关告警 |
典型使用场景
- 高并发短连接场景下客户端报连接超时,需要确认内核队列是否成为瓶颈
- 压测中出现连接失败率,排查是应用侧还是内核参数侧
- 把 Redis 部署到默认参数较小的老内核上,需要一并调整系统基线
- 容器化部署后性能不如预期,检查容器网络命名空间里的参数值
- 变更 Redis tcp-backlog 前,先确认内核上限是否足以支撑
- 做系统基线巡检时核对关键网络参数是否符合规范
查看与调整
查看与调整
sysctl net.core.somaxconn # 当前全连接队列上限
sysctl net.ipv4.tcp_max_syn_backlog # 半连接队列上限
redis-cli CONFIG GET tcp-backlog # Redis 侧申请的队列长度
sysctl -w net.core.somaxconn=4096 # 临时生效,重启丢失
printf 'net.core.somaxconn=4096\n' > /etc/sysctl.d/99-redis.conf
sysctl -p /etc/sysctl.d/99-redis.conf # 持久化后重新加载
ss -lnt | grep 6379 # Send-Q 列即监听的 backlog参数对照
| 参数 | 作用 | 注意 |
|---|---|---|
| net.core.somaxconn | 全连接队列上限 | 老内核默认 128,新内核更大 |
| tcp_max_syn_backlog | 半连接队列上限 | SYN 洪泛场景更敏感 |
| tcp-backlog | Redis 申请的队列长度 | 大于内核值时被静默压低 |
| somaxconn 修改后 | 需重启进程或系统 | 已监听套接字不会自动扩队 |
somaxconn 的默认值随内核版本变化,评估以 sysctl 实测为准,不要照抄他人文档里的数字。
容器有独立的网络命名空间,宿主上改过不代表容器里生效;要按 容器内检查加宿主检查 两步走。
改内核网络参数属系统级变更,会影响同机其他服务,走变更流程并记录修改前后的基线值。