Go 应用中的 Redis 连接与操作
安装与模块初始化
-
初始化 Go 模块
go mod init github.com/yourusername/yourrepo
-
获取 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, // 默认使用 DB0Protocol: 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 等后端。
生产环境最佳实践
-
连接池调优
Options.PoolSize
、MinIdleConns
、PoolTimeout
等参数根据业务并发场景调整。
-
重试与断路器
- 对关键写操作,启用
Options.MaxRetries
,并结合github.com/sethvargo/go-retry
实现限流、退避重试。
- 对关键写操作,启用
-
心跳检测
- 定期执行
PING
或自定义 Lua 脚本,检测集群节点健康。
- 定期执行
-
安全加固
- 开启 ACL、TLS 加密,避免明文传输和未授权访问。
-
监控与告警
- 利用 redisotel、Redis 内置 INFO 命令及
redis_exporter
打通 Prometheus → Alertmanager → PagerDuty 告警链路。
- 利用 redisotel、Redis 内置 INFO 命令及
更多资源
- 🔗 go-redis 官方文档:https://pkg.go.dev/github.com/redis/go-redis/v9
- 🔗 GitHub 仓库:https://github.com/redis/go-redis
- 🔗 OpenTelemetry 支持示例:
extra/redisotel/v9
通过以上内容,你已掌握使用 go-redis 在 Go 应用中进行基础操作、结构体映射、可观测集成与生产环境优化的核心要点。Happy coding!