跳转至

第五章:客户端连接

连接方式

命令行连接

# 连接集群
redis-cli -c -h 192.168.1.101 -p 6379

# 参数说明
-c: 集群模式,自动重定向
-h: 主机地址
-p: 端口号
-a: 密码

连接池

# Python redis-py-cluster
from rediscluster import RedisCluster

# 连接配置
startup_nodes = [
    {'host': '192.168.1.101', 'port': 6379},
    {'host': '192.168.1.102', 'port': 6379},
    {'host': '192.168.1.103', 'port': 6379},
]

# 创建连接
rc = RedisCluster(
    startup_nodes=startup_nodes,
    decode_responses=True,
    password='your-password',
    max_connections=100,
)

Python 客户端

安装依赖

pip install redis-py-cluster

基本操作

from rediscluster import RedisCluster

# 连接集群
startup_nodes = [
    {'host': '192.168.1.101', 'port': 6379},
]
rc = RedisCluster(startup_nodes=startup_nodes, decode_responses=True)

# 字符串操作
rc.set('user:1', 'John')
print(rc.get('user:1'))  # John

# 哈希操作
rc.hset('user:1:info', 'name', 'John')
rc.hset('user:1:info', 'age', 25)
print(rc.hgetall('user:1:info'))

# 列表操作
rc.lpush('queue:tasks', 'task1', 'task2')
print(rc.lrange('queue:tasks', 0, -1))

# 集合操作
rc.sadd('users:active', 'user:1', 'user:2')
print(rc.smembers('users:active'))

# 有序集合
rc.zadd('leaderboard', {'user:1': 100, 'user:2': 200})
print(rc.zrange('leaderboard', 0, -1, withscores=True))

管道操作

# 使用管道批量操作
with rc.pipeline() as pipe:
    pipe.set('key1', 'value1')
    pipe.set('key2', 'value2')
    pipe.set('key3', 'value3')
    pipe.execute()

事务操作

# 使用哈希标签确保事务
with rc.pipeline() as pipe:
    while True:
        try:
            pipe.watch('user:{1}:balance')
            balance = int(pipe.get('user:{1}:balance'))
            pipe.multi()
            pipe.set('user:{1}:balance', balance - 100)
            pipe.execute()
            break
        except Exception:
            continue

Java 客户端

Jedis 集群

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.3.1</version>
</dependency>
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.HostAndPort;
import java.util.Set;
import java.util.HashSet;

// 连接配置
Set<HostAndPort> nodes = new HashSet<>();
nodes.add(new HostAndPort("192.168.1.101", 6379));
nodes.add(new HostAndPort("192.168.1.102", 6379));
nodes.add(new HostAndPort("192.168.1.103", 6379));

// 创建连接
JedisCluster jc = new JedisCluster(nodes);

// 基本操作
jc.set("user:1", "John");
String value = jc.get("user:1");

// 哈希操作
jc.hset("user:1:info", "name", "John");
Map<String, String> info = jc.hgetAll("user:1:info");

// 关闭连接
jc.close();

Lettuce 集群

<dependency>
    <groupId>io.lettuce</groupId>
    <artifactId>lettuce-core</artifactId>
    <version>6.2.0</version>
</dependency>
import io.lettuce.core.RedisClient;
import io.lettuce.core.cluster.RedisClusterClient;
import io.lettuce.core.cluster.api.StatefulRedisClusterConnection;

// 连接配置
RedisClusterClient client = RedisClusterClient.create(
    "redis://192.168.1.101:6379," +
    "redis://192.168.1.102:6379," +
    "redis://192.168.1.103:6379"
);

// 创建连接
StatefulRedisClusterConnection<String, String> connection = client.connect();

// 基本操作
connection.sync().set("user:1", "John");
String value = connection.sync().get("user:1");

// 关闭连接
connection.close();
client.shutdown();

Go 客户端

go-redis 集群

package main

import (
    "context"
    "fmt"
    "github.com/go-redis/redis/v8"
)

func main() {
    // 连接配置
    rdb := redis.NewClusterClient(&redis.ClusterOptions{
        Addrs: []string{
            "192.168.1.101:6379",
            "192.168.1.102:6379",
            "192.168.1.103:6379",
        },
        Password: "",
        PoolSize: 100,
    })
    defer rdb.Close()

    ctx := context.Background()

    // 基本操作
    err := rdb.Set(ctx, "user:1", "John", 0).Err()
    if err != nil {
        panic(err)
    }

    val, err := rdb.Get(ctx, "user:1").Result()
    if err != nil {
        panic(err)
    }
    fmt.Println("user:1 =", val)

    // 哈希操作
    rdb.HSet(ctx, "user:1:info", "name", "John")
    rdb.HSet(ctx, "user:1:info", "age", 25)

    info, _ := rdb.HGetAll(ctx, "user:1:info").Result()
    fmt.Println(info)
}

连接优化

连接池配置

# Python 连接池配置
rc = RedisCluster(
    startup_nodes=startup_nodes,
    max_connections=100,      # 最大连接数
    socket_timeout=5,         # Socket 超时
    socket_connect_timeout=5, # 连接超时
    retry_on_timeout=True,    # 超时重试
    max_attempts=3,           # 最大重试次数
)

重试策略

from rediscluster import RedisCluster
from redis.exceptions import RedisError
import time

def redis_operation_with_retry(rc, operation, *args, **kwargs):
    max_retries = 3
    for i in range(max_retries):
        try:
            return operation(*args, **kwargs)
        except RedisError as e:
            if i == max_retries - 1:
                raise
            time.sleep(0.1 * (i + 1))

小结

客户端连接要点:

  • 连接方式:命令行、连接池
  • Python 客户端:基本操作、管道、事务
  • Java 客户端:Jedis、Lettuce
  • Go 客户端:go-redis
  • 连接优化:连接池配置、重试策略

下一章我们将学习监控运维。