Redis 连接(Connection)完全攻略
“Redis 的命脉” —— 理解连接原理、优化连接池、避免连接泄漏,性能提升 10 倍!
一、Redis 连接核心概念
| 概念 | 说明 |
|---|---|
| TCP 连接 | Redis 基于 长连接,一次握手多次命令 |
| 连接生命周期 | CONNECT → AUTH → SELECT → 命令 → QUIT |
| 最大连接数 | 默认 无限,受 maxclients 限制 |
| 连接模式 | 普通 / 订阅 / 事务 / 管道 |
| 连接状态 | idle、active、blocked |
二、连接相关配置(redis.conf)
| 配置 | 默认值 | 说明 | 推荐 |
|---|---|---|---|
bind 127.0.0.1 | 本地 | 监听地址 | 生产内网 IP |
port 6379 | 6379 | 端口 | 自定义 |
timeout 0 | 0 | 空闲超时(秒) | 300 |
tcp-keepalive 300 | 300 | TCP 保活 | 60 |
maxclients 10000 | 10000 | 最大客户端数 | CPU核 × 10000 |
client-output-buffer-limit | 见下 | 客户端缓冲区 | 调整 |
客户端缓冲区限制(防 OOM)
# 格式: normal {soft} {hard} {sec}
client-output-buffer-limit normal 0 0 0
client-output-buffer-limit replica 256mb 64mb 60
client-output-buffer-limit pubsub 32mb 8mb 60
三、连接命令全表
| 命令 | 说明 | 示例 |
|---|---|---|
CLIENT LIST | 查看所有连接 | CLIENT LIST |
CLIENT GETNAME | 获取连接名 | CLIENT GETNAME |
CLIENT SETNAME name | 设置连接名 | CLIENT SETNAME web:1 |
CLIENT ID | 当前连接 ID | CLIENT ID |
CLIENT KILL addr:port | 断开指定连接 | CLIENT KILL 127.0.0.1:12345 |
CLIENT PAUSE timeout | 暂停所有客户端 | CLIENT PAUSE 1000 |
CLIENT REPLY ON|OFF|SKIP | 控制回复 | CLIENT REPLY OFF |
CLIENT INFO | 当前连接信息 | CLIENT INFO |
四、连接状态详解(CLIENT LIST 输出)
id=5 addr=127.0.0.1:54321 fd=8 name=web:1 age=120 idle=0 flags=N
| 字段 | 说明 |
|---|---|
id | 连接唯一 ID |
addr | 客户端 IP:端口 |
fd | 文件描述符 |
name | 连接名(CLIENT SETNAME) |
age | 连接存活时间(秒) |
idle | 空闲时间(秒) |
flags | 状态标志:N=普通,S=从库,P=Pub/Sub,M=Monitor |
五、连接池(Connection Pool)最佳实践
为什么需要连接池?
创建连接 → TCP 3次握手 → 慢!
复用连接 → 零开销 → 快!
连接池参数推荐
| 参数 | 推荐值 | 说明 |
|---|---|---|
max_total | CPU核 × 100 | 总连接数 |
max_idle | CPU核 × 20 | 空闲连接 |
min_idle | CPU核 × 5 | 最小空闲 |
max_wait | 100ms | 获取连接超时 |
test_on_borrow | true | 借出时校验 |
test_on_return | false | 归还时不校验 |
六、客户端连接代码示例
Python (redis-py + 连接池)
import redis
# 创建连接池
pool = redis.ConnectionPool(
host='127.0.0.1',
port=6379,
password='your_password',
max_connections=20,
socket_timeout=5,
socket_connect_timeout=5,
retry_on_timeout=True,
health_check_interval=30
)
# 复用连接池
r = redis.Redis(connection_pool=pool)
# 设置连接名
r.client_setname('web:worker:1')
# 使用
r.set('key', 'value')
Java (Jedis + 连接池)
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(50);
config.setMaxIdle(10);
config.setMinIdle(5);
config.setTestOnBorrow(true);
JedisPool pool = new JedisPool(config, "localhost", 6379, 5000, "password");
try (Jedis jedis = pool.getResource()) {
jedis.clientSetname("api:service:1");
jedis.set("key", "value");
}
Go (go-redis)
rdb := redis.NewClient(&redis.Options{
Addr: "localhost:6379",
Password: "password",
DB: 0,
PoolSize: 20,
MinIdleConns: 5,
DialTimeout: 5 * time.Second,
ReadTimeout: 3 * time.Second,
WriteTimeout: 3 * time.Second,
PoolTimeout: 5 * time.Second,
})
rdb.ClientSetName(context.Background(), "go:worker:1")
七、连接优化技巧
| 技巧 | 说明 |
|---|---|
| 设置连接名 | CLIENT SETNAME 便于监控 |
| 短连接 → 长连接 | 复用连接 |
| 连接池预热 | 启动时创建 min_idle 连接 |
| 超时设置 | socket_timeout、connect_timeout |
| 心跳检测 | PING 每 30 秒 |
关闭 CLIENT REPLY OFF | 订阅模式下使用 |
# 心跳
def heartbeat(r):
while True:
r.ping()
time.sleep(30)
八、连接问题排查
1. 连接数暴涨
CLIENT LIST | wc -l # 当前连接数
INFO clients # connected_clients
原因:
- 连接泄漏
- 连接池配置过大
- 订阅者未退出
解决:
# 杀掉空闲 > 1小时的连接
CLIENT LIST | grep "idle=3600" | awk '{print $2}' | cut -d: -f1 | xargs -I {} CLIENT KILL {}
2. 连接超时
Error: Connection timed out
解决:
- 增大
socket_timeout - 检查网络延迟
- 使用连接池
3. Too many open files
Error: Too many open files
解决:
ulimit -n 65535
# redis.conf
maxclients 10000
九、一键速查表
# 连接管理
CLIENT LIST
CLIENT LIST | grep "idle=3600" | wc -l
CLIENT KILL 127.0.0.1:54321
CLIENT SETNAME web:1
CLIENT GETNAME
# 监控
INFO clients
INFO stats | grep connected
# 配置
timeout 300
tcp-keepalive 60
maxclients 20000
十、连接安全加固
# 1. 密码认证
requirepass your_strong_password
# 2. 禁用危险命令
rename-command FLUSHALL ""
rename-command CONFIG "CONFIG_PROD"
# 3. 绑定内网
bind 10.0.0.10
# 4. TLS 加密(Redis 6.0+)
tls-port 6380
tls-cert-file /path/redis.crt
tls-key-file /path/redis.key
十一、生产级连接架构
graph TD
A[应用服务] -->|连接池| P[Proxy]
P[Sentinel / Cluster Proxy] --> R1[Redis 主]
P --> R2[Redis 从]
P --> R3[Redis 从]
推荐方案:
- Sentinel 模式:
redis-sentinel+ 连接池 - Cluster 模式:
redis-cluster-proxy或客户端智能连接 - 连接池中间件:
Hiredis+Twemproxy
完成!你已精通 Redis 连接!
# 一行命令查看连接健康状态
redis-cli CLIENT LIST | awk '{print $2" "$5" "$6}' | sort
下一步推荐:
需要我送你:
- “企业级连接池配置模板(Java/Python/Go)”?
- “连接泄漏自动检测 + 告警脚本”?
- “Redis 连接监控大屏(Grafana)”?
回复:连接池模板 | 泄漏检测 | 监控大屏 即可!