Redis 客户端连接全攻略(2025 版)
核心目标:稳定、高效、安全地连接 Redis,应对 高并发、长连接、连接池、故障切换、TLS、限流 等生产场景。
1. 连接基础原理
| 项目 | 说明 |
|---|
| 协议 | RESP(REdis Serialization Protocol),基于 TCP |
| 默认端口 | 6379(明文),6380/6381(TLS) |
| 连接模式 | 长连接(复用 TCP),不要短连接 |
| 认证方式 | AUTH <password> 或 AUTH <username> <password>(ACL) |
| 最大连接数 | tcp-backlog + OS somaxconn 限制 |
2. 客户端连接最佳实践(通用规则)
| 规则 | 推荐配置 |
|---|
| 连接池 | 必须使用,控制连接数 |
| 超时时间 | 读写超时 ≤ 500ms,连接超时 ≤ 200ms |
| 重试策略 | 指数退避,最大 3 次 |
| 心跳检测 | PING 每 10~30s |
| TLS 加密 | 生产必须开启 |
| 连接泄漏监控 | 告警 connected_clients > 阈值 |
3. 主流语言客户端配置(生产级模板)
3.1 Java(Jedis / Lettuce)
Lettuce(推荐,异步 + Netty)
<!-- pom.xml -->
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>6.4.0.RELEASE</version>
</dependency>
// 单机 + TLS + 连接池
RedisURI uri = RedisURI.builder()
.withHost("redis-prod.example.com")
.withPort(6379)
.withPassword("YourStrongP@ssw0rd".toCharArray())
.withSsl(true)
.withVerifyPeer(false) // 生产用 CA
.build();
GenericObjectPoolConfig<StatefulRedisConnection<String, String>> poolConfig =
new GenericObjectPoolConfig<>();
poolConfig.setMaxTotal(50);
poolConfig.setMaxIdle(20);
poolConfig.setMinIdle(5);
poolConfig.setTestOnBorrow(true);
RedisClient client = RedisClient.create(uri);
ConnectionPool<StatefulRedisConnection<String, String>> pool =
ConnectionPool.create(client, poolConfig);
try (StatefulRedisConnection<String, String> conn = pool.borrowObject()) {
RedisCommands<String, String> sync = conn.sync();
sync.set("key", "value");
}
Spring Boot 集成(Lettuce)
# application.yml
spring:
redis:
host: redis-prod.example.com
port: 6379
password: YourStrongP@ssw0rd
ssl: true
timeout: 500ms
lettuce:
pool:
max-active: 50
max-idle: 20
min-idle: 5
3.2 Python(redis-py)
pip install redis[hiredis]
import redis
from redis.connection import SSLConnection
pool = redis.ConnectionPool(
host='redis-prod.example.com',
port=6379,
password='YourStrongP@ssw0rd',
socket_timeout=0.5,
socket_connect_timeout=0.2,
retry_on_timeout=True,
retry=redis.Retry(redis.BackoffRetry(3), 0.1),
health_check_interval=30,
ssl=True,
ssl_cert_reqs="required",
ssl_ca_certs="/path/to/ca.crt",
max_connections=50
)
r = redis.Redis(connection_pool=pool)
r.ping() # 心跳
3.3 Go(go-redis)
go get github.com/redis/go-redis/v9
package main
import (
"context"
"crypto/tls"
"time"
"github.com/redis/go-redis/v9"
)
func main() {
client := redis.NewClient(&redis.Options{
Addr: "redis-prod.example.com:6379",
Password: "YourStrongP@ssw0rd",
DB: 0,
TLSConfig: &tls.Config{
InsecureSkipVerify: false, // 生产关闭
},
PoolSize: 50,
MinIdleConns: 5,
DialTimeout: 200 * time.Millisecond,
ReadTimeout: 500 * time.Millisecond,
WriteTimeout: 500 * time.Millisecond,
PoolTimeout: 1 * time.Second,
IdleTimeout: 5 * time.Minute,
OnConnect: func(ctx context.Context, cn *redis.Conn) error {
return cn.Ping(ctx).Err()
},
})
ctx := context.Background()
if err := client.Ping(ctx).Err(); err != nil {
panic(err)
}
}
3.4 Node.js(ioredis)
npm install ioredis
const Redis = require('ioredis');
const redis = new Redis({
host: 'redis-prod.example.com',
port: 6379,
password: 'YourStrongP@ssw0rd',
tls: {
rejectUnauthorized: true,
ca: [require('fs').readFileSync('/path/to/ca.crt')]
},
maxRetriesPerRequest: 3,
retryStrategy: times => Math.min(times * 100, 2000),
reconnectOnError: err => err.message.includes('READONLY'),
lazyConnect: true,
connectionLimit: 50,
keepAlive: 30000
});
// 心跳
setInterval(() => redis.ping(), 30000);
4. 连接池参数调优(关键)
| 参数 | 推荐值 | 说明 |
|---|
maxTotal / PoolSize | CPU核数 × 50 ~ 100 | 总连接数 |
maxIdle / MinIdleConns | 10 ~ 20 | 空闲连接 |
testOnBorrow / health_check | true | 借出前 PING |
timeout | 200ms ~ 500ms | 避免阻塞 |
pipeline | 开启 | 批量操作 |
5. 高可用连接方案
5.1 Sentinel(哨兵)
// Lettuce + Sentinel
RedisURI uri = RedisURI.builder()
.withSentinel("sentinel1", 26379)
.withSentinel("sentinel2", 26379)
.withSentinelMasterId("mymaster")
.withPassword("password")
.build();
5.2 Cluster(集群)
// Lettuce + Cluster
Set<RedisURI> nodes = Set.of(
RedisURI.create("redis://node1:6379"),
RedisURI.create("redis://node2:6379")
);
RedisClusterClient clusterClient = RedisClusterClient.create(nodes);
6. 连接安全加固
| 措施 | 配置 |
|---|
| TLS 加密 | ssl: true, tls-port 6379 |
| ACL 认证 | AUTH appuser appsecret |
| IP 白名单 | 防火墙 / VPC |
| 连接加密验证 | ssl_cert_reqs="required" |
| 禁用明文端口 | port 0 |
7. 连接监控与告警
7.1 Redis 端监控
redis-cli INFO clients
# connected_clients: 850
# rejected_connections: 12
# blocked_clients: 3
7.2 客户端监控
| 指标 | 工具 |
|---|
| 连接池使用率 | Micrometer / Prometheus |
| 响应时间 | INFO commandstats |
| 错误率 | rejected, timeout |
Prometheus 指标示例:
redis_connected_clients{instance="prod"} 850
redis_rejected_connections_total 12
8. 常见连接问题与排查
| 问题 | 原因 | 解决方案 |
|---|
Connection timed out | 网络/防火墙 | telnet 6379 |
READONLY | 连接到从库 | 使用主库或 READONLY 命令 |
MAX NUMBER OF CLIENTS | 超过 maxclients | 调大 maxclients 65536 |
Connection reset by peer | 空闲超时 | 调大 timeout 0 或心跳 |
Authentication failed | 密码错误 | 检查 ACL / requirepass |
9. 一键连接测试脚本
#!/bin/bash
# redis_conn_test.sh
HOST=$1
PORT=${2:-6379}
PASS=$3
echo "Testing connection to $HOST:$PORT..."
# 1. 网络连通性
nc -zv $HOST $PORT && echo "TCP OK"
# 2. Redis PING
redis-cli -h $HOST -p $PORT ${PASS:+-a $PASS} PING | grep -q PONG && echo "PING OK"
# 3. TLS 测试
if [[ $PORT -eq 6380 ]]; then
openssl s_client -connect $HOST:$PORT -quiet </dev/null 2>/dev/null && echo "TLS OK"
fi
# 4. 连接数
redis-cli -h $HOST -p $PORT ${PASS:+-a $PASS} INFO clients | grep connected_clients
使用:
./redis_conn_test.sh redis-prod.example.com 6379 YourPassword
10. 最佳实践清单(Checklist)
| 项目 | 检查 |
|---|
| 使用连接池 | maxTotal 合理 |
| 启用 TLS | ssl: true |
| 超时 < 500ms | socket_timeout |
| 心跳 PING | 每 30s |
| 监控连接数 | connected_clients |
| ACL 最小权限 | ~app:* +@read |
| 重试策略 | 指数退避 |
| 连接泄漏检测 | 告警 > 80% |
小结
| 场景 | 推荐客户端 |
|---|
| 高性能 | Lettuce(Java), go-redis |
| 异步/事件驱动 | ioredis(Node.js) |
| 脚本/运维 | redis-py |
| Spring Boot | Lettuce(默认) |
需要 连接池压测、K8s Sidecar 注入、连接泄漏检测脚本 或 多语言统一配置中心?随时告诉我!