Redis 客户端连接

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 / PoolSizeCPU核数 × 50 ~ 100总连接数
maxIdle / MinIdleConns10 ~ 20空闲连接
testOnBorrow / health_checktrue借出前 PING
timeout200ms ~ 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 合理
启用 TLSssl: true
超时 < 500mssocket_timeout
心跳 PING每 30s
监控连接数connected_clients
ACL 最小权限~app:* +@read
重试策略指数退避
连接泄漏检测告警 > 80%

小结

场景推荐客户端
高性能Lettuce(Java), go-redis
异步/事件驱动ioredis(Node.js)
脚本/运维redis-py
Spring BootLettuce(默认)

需要 连接池压测K8s Sidecar 注入连接泄漏检测脚本多语言统一配置中心?随时告诉我!

文章已创建 2481

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

相关文章

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部