Redis操作

基本连接

Redis连接和基本操作。

package main

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

func main() {
    // 创建Redis客户端
    rdb := redis.NewClient(&redis.Options{
        Addr:     "localhost:6379",
        Password: "", // 无密码
        DB:       0,  // 默认DB
    })

    // 创建上下文
    ctx := context.Background()

    // 测试连接
    err := rdb.Ping(ctx).Err()
    if err != nil {
        panic(err)
    }

    // 设置键值对
    err = rdb.Set(ctx, "key", "value", 0).Err()
    if err != nil {
        panic(err)
    }

    // 获取值
    val, err := rdb.Get(ctx, "key").Result()
    if err != nil {
        panic(err)
    }
    fmt.Println("key:", val)

    // 删除键
    err = rdb.Del(ctx, "key").Err()
    if err != nil {
        panic(err)
    }
}

数据类型操作

Redis各种数据类型的操作。

// 1. 字符串操作
rdb.Set(ctx, "string", "value", 0)
rdb.Get(ctx, "string")
rdb.Incr(ctx, "counter")
rdb.Decr(ctx, "counter")

// 2. 列表操作
rdb.LPush(ctx, "list", "value1")
rdb.RPush(ctx, "list", "value2")
rdb.LRange(ctx, "list", 0, -1)
rdb.LPop(ctx, "list")

// 3. 集合操作
rdb.SAdd(ctx, "set", "member1")
rdb.SMembers(ctx, "set")
rdb.SIsMember(ctx, "set", "member1")
rdb.SRem(ctx, "set", "member1")

// 4. 有序集合操作
rdb.ZAdd(ctx, "zset", redis.Z{Score: 1, Member: "member1"})
rdb.ZRange(ctx, "zset", 0, -1)
rdb.ZScore(ctx, "zset", "member1")
rdb.ZRem(ctx, "zset", "member1")

// 5. 哈希表操作
rdb.HSet(ctx, "hash", "field1", "value1")
rdb.HGet(ctx, "hash", "field1")
rdb.HGetAll(ctx, "hash")
rdb.HDel(ctx, "hash", "field1")

事务操作

Redis事务的使用。

// 使用事务
func transactionExample(ctx context.Context, rdb *redis.Client) error {
    // 开始事务
    tx := rdb.TxPipeline()

    // 执行多个命令
    tx.Set(ctx, "key1", "value1", 0)
    tx.Set(ctx, "key2", "value2", 0)
    tx.Incr(ctx, "counter")

    // 执行事务
    _, err := tx.Exec(ctx)
    return err
}

// 使用Watch实现乐观锁
func watchExample(ctx context.Context, rdb *redis.Client) error {
    // 监视key
    err := rdb.Watch(ctx, func(tx *redis.Tx) error {
        // 获取当前值
        n, err := tx.Get(ctx, "key").Int()
        if err != nil && err != redis.Nil {
            return err
        }

        // 在事务中修改值
        _, err = tx.TxPipelined(ctx, func(pipe redis.Pipeliner) error {
            pipe.Set(ctx, "key", n+1, 0)
            return nil
        })
        return err
    }, "key")
    return err
}

发布订阅

Redis发布订阅功能。

// 发布者
func publisher(ctx context.Context, rdb *redis.Client) {
    // 发布消息
    err := rdb.Publish(ctx, "channel", "message").Err()
    if err != nil {
        panic(err)
    }
}

// 订阅者
func subscriber(ctx context.Context, rdb *redis.Client) {
    // 创建订阅
    pubsub := rdb.Subscribe(ctx, "channel")
    defer pubsub.Close()

    // 接收消息
    ch := pubsub.Channel()
    for msg := range ch {
        fmt.Println(msg.Channel, msg.Payload)
    }
}

// 模式订阅
func patternSubscriber(ctx context.Context, rdb *redis.Client) {
    // 创建模式订阅
    pubsub := rdb.PSubscribe(ctx, "channel*")
    defer pubsub.Close()

    // 接收消息
    ch := pubsub.Channel()
    for msg := range ch {
        fmt.Println(msg.Channel, msg.Payload)
    }
}

连接池管理

Redis连接池配置。

// 配置连接池
rdb := redis.NewClient(&redis.Options{
    Addr:         "localhost:6379",
    Password:     "",
    DB:           0,
    PoolSize:     10,               // 连接池大小
    MinIdleConns: 5,               // 最小空闲连接数
    MaxRetries:   3,               // 最大重试次数
    IdleTimeout:  5 * time.Minute, // 空闲连接超时时间
    MaxConnAge:   1 * time.Hour,   // 连接最大生命周期
})

// 使用连接池
func poolExample(ctx context.Context, rdb *redis.Client) {
    // 获取连接池统计信息
    stats := rdb.PoolStats()
    fmt.Printf("TotalConns: %d\n", stats.TotalConns)
    fmt.Printf("IdleConns: %d\n", stats.IdleConns)
    fmt.Printf("StaleConns: %d\n", stats.StaleConns)
}

最佳实践

Redis使用的最佳实践。

# 1. 连接管理
- 使用连接池
- 及时关闭连接
- 处理连接错误
- 实现重试机制

# 2. 键值设计
- 使用合适的键名
- 设置过期时间
- 避免大键
- 使用合适的数据类型

# 3. 性能优化
- 使用Pipeline
- 使用事务
- 避免阻塞操作
- 使用批量操作

# 4. 高可用
- 使用主从复制
- 使用哨兵模式
- 使用集群模式
- 实现故障转移

# 5. 监控
- 监控内存使用
- 监控连接数
- 监控命令执行
- 监控慢查询