Go 应用中的 Redis 连接与操作

发布于:2025-05-28 ⋅ 阅读:(14) ⋅ 点赞:(0)

安装与模块初始化

  1. 初始化 Go 模块

    go mod init github.com/yourusername/yourrepo
    
  2. 获取 go-redis
    go-redis v9 支持最新两个 Go 版本:

    go get github.com/redis/go-redis/v9
    

建立连接

1. 最简方式

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

func main() {
    ctx := context.Background()

    client := redis.NewClient(&redis.Options{
        Addr:     "localhost:6379",
        Password: "", // 若设置了密码则填入
        DB:       0,  // 默认使用 DB0
        Protocol: 2,  // Redis 协议版本(通常无须修改)
    })

    // 测试连通性
    err := client.Ping(ctx).Err()
    if err != nil {
        panic(err)
    }
    fmt.Println("✅ Redis connected")
}

2. 使用连接字符串

opt, err := redis.ParseURL("redis://user:pass@localhost:6379/1")
if err != nil {
    panic(err)
}
client := redis.NewClient(opt)

基本读写示例

字符串操作

// 设置 key
if err := client.Set(ctx, "foo", "bar", 0).Err(); err != nil {
    panic(err)
}

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

哈希操作

fields := []string{
    "model", "Deimos",
    "brand", "Ergonom",
    "type",  "Enduro bikes",
    "price", "4972",
}

// HSET
if n, err := client.HSet(ctx, "bike:1", fields...).Result(); err != nil {
    panic(err)
} else {
    fmt.Printf("↪ %d fields set\n", n) // ↪ 4 fields set
}

// HGET
model, _ := client.HGet(ctx, "bike:1", "model").Result()
price, _ := client.HGet(ctx, "bike:1", "price").Result()
fmt.Println("model:", model, "price:", price)

// HGETALL 并 Scan 到结构体
type BikeInfo struct {
    Model string `redis:"model"`
    Brand string `redis:"brand"`
    Type  string `redis:"type"`
    Price int    `redis:"price"`
}

var info BikeInfo
if err := client.HGetAll(ctx, "bike:1").Scan(&info); err != nil {
    panic(err)
}
fmt.Printf("%+v\n", info)
// 输出:{Model:Deimos Brand:Ergonom Type:Enduro bikes Price:4972}

管道与事务(Pipelines & Transactions)

管道示例

管道(Pipeline)可将多条命令一次性发送并批量接收结果,减少网络往返:

pipe := client.Pipeline()
incr := pipe.Incr(ctx, "pipeline_counter")
pipe.Expire(ctx, "pipeline_counter", time.Hour)
results, err := pipe.Exec(ctx)
if err != nil {
    panic(err)
}
fmt.Println("New counter:", incr.Val(), "Results:", results)

事务示例

事务(TXPipelined)可在乐观锁或 MULTI/EXEC 模式下执行:

err := client.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")
if err != nil {
    panic(err)
}

OpenTelemetry 可观测性

在生产环境中,监控 Redis 命令性能与分布式追踪至关重要。go-redis 提供了 redisotel 插件:

import (
    "github.com/redis/go-redis/v9"
    "github.com/redis/go-redis/extra/redisotel/v9"
)

client := redis.NewClient(&redis.Options{ /* ... */ })

// 启用追踪
if err := redisotel.InstrumentTracing(client); err != nil {
    panic(err)
}

// 启用指标
if err := redisotel.InstrumentMetrics(client); err != nil {
    panic(err)
}

完成后,你的 Redis 操作将自动生成 OpenTelemetry spans 和 metrics,可接入 Jaeger、Prometheus 等后端。


生产环境最佳实践

  1. 连接池调优

    • Options.PoolSizeMinIdleConnsPoolTimeout 等参数根据业务并发场景调整。
  2. 重试与断路器

    • 对关键写操作,启用 Options.MaxRetries,并结合 github.com/sethvargo/go-retry 实现限流、退避重试。
  3. 心跳检测

    • 定期执行 PING 或自定义 Lua 脚本,检测集群节点健康。
  4. 安全加固

    • 开启 ACL、TLS 加密,避免明文传输和未授权访问。
  5. 监控与告警

    • 利用 redisotel、Redis 内置 INFO 命令及 redis_exporter 打通 Prometheus → Alertmanager → PagerDuty 告警链路。

更多资源

通过以上内容,你已掌握使用 go-redis 在 Go 应用中进行基础操作、结构体映射、可观测集成与生产环境优化的核心要点。Happy coding!


网站公告

今日签到

点亮在社区的每一天
去签到