Go从入门到精通(24) - 一个简单web项目-添加redis缓存
Go从入门到精通(24)
一个简单web项目-添加redis缓存
文章目录
- Go从入门到精通(24)
- 前言
- 缓存流程说明
- 查询流程
- 更新流程
- 缓存策略
- 优势
- redis使用
- 安装依赖
- 配置 Redis 连接
- 修改用户处理函数添加缓存
- 修改主函数初始化 Redis
- 配置环境变量
前言
在 Go 语言中使用 Redis 缓存频繁访问的数据,可以显著提升应用性能。
缓存流程说明
查询流程
- Cache Hit → 直接返回缓存数据
- Cache Miss → 查询数据库 → 写入缓存 → 返回数据
更新流程
- 更新数据库 → 删除缓存(而非更新)→ 下次查询时自动刷新
缓存策略
- 使用 JSON 序列化存储对象
- 设置 5 分钟过期时间(根据业务需求调整)
- 采用Read-Through和Write-Invalidate策略
优势
- 减少数据库压力(高频访问的数据仅第一次查询 DB)
- 提升响应速度(Redis 读取延迟通常 < 1ms)
- 支持分布式缓存(多实例共享同一 Redis)
redis使用
安装依赖
go get github.com/go-redis/redis/v8
配置 Redis 连接
// cache/redis.go
package cacheimport ("context""fmt""log""os""strconv""strings""time""github.com/go-redis/redis/v8"
)var RedisClient redis.UniversalClient
var Ctx = context.Background()func InitRedis() {// 从环境变量获取 Redis 配置mode := os.Getenv("REDIS_MODE")if mode == "" {mode = "single" // 默认单节点模式}switch mode {case "cluster":// 集群模式addresses := os.Getenv("REDIS_CLUSTER_ADDRESSES")if addresses == "" {log.Fatal("REDIS_CLUSTER_ADDRESSES 环境变量未设置")}password := os.Getenv("REDIS_PASSWORD")RedisClient = redis.NewClusterClient(&redis.ClusterOptions{Addrs: strings.Split(addresses, ","),Password: password,// 其他可选配置MaxRetries: 3,MinRetryBackoff: 8 * time.Millisecond,MaxRetryBackoff: 512 * time.Millisecond,DialTimeout: 5 * time.Second,ReadTimeout: 3 * time.Second,WriteTimeout: 3 * time.Second,PoolSize: 100,MinIdleConns: 20,})default:// 单节点模式host := os.Getenv("REDIS_HOST")if host == "" {host = "localhost"}port := os.Getenv("REDIS_PORT")if port == "" {port = "6379"}password := os.Getenv("REDIS_PASSWORD")db, _ := strconv.Atoi(os.Getenv("REDIS_DB"))RedisClient = redis.NewClient(&redis.Options{Addr: fmt.Sprintf("%s:%s", host, port),Password: password,DB: db,// 其他可选配置MaxRetries: 3,MinRetryBackoff: 8 * time.Millisecond,MaxRetryBackoff: 512 * time.Millisecond,DialTimeout: 5 * time.Second,ReadTimeout: 3 * time.Second,WriteTimeout: 3 * time.Second,PoolSize: 100,MinIdleConns: 20,})}// 测试连接if mode == "cluster" {_, err := RedisClient.Ping(Ctx).Result()if err != nil {log.Fatalf("无法连接到 Redis Cluster: %v", err)}log.Println("Redis Cluster 连接成功")} else {_, err := RedisClient.Ping(Ctx).Result()if err != nil {log.Fatalf("无法连接到 Redis: %v", err)}log.Println("Redis 单节点连接成功")}
}
修改用户处理函数添加缓存
func GetCurrentUserHandler(c *gin.Context) {userID := c.MustGet("user_id").(string)// 1. 先从 Redis 缓存中获取cacheKey := fmt.Sprintf("user:%s", userID)userJSON, err := cache.RedisClient.Get(cache.Ctx, cacheKey).Result()if err == nil {// 缓存命中var user models.Userif err := json.Unmarshal([]byte(userJSON), &user); err == nil {c.JSON(http.StatusOK, user)return}}// 2. 缓存未命中,从数据库获取user, exists := users[userID]if !exists {c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})return}// 不返回密码user.Password = ""// 3. 将数据存入 Redis 缓存(设置 5 分钟过期)userByteArray, err := json.Marshal(user)if err == nil {userJSON = string(userByteArray)cache.RedisClient.Set(cache.Ctx, cacheKey, userJSON, 5*time.Minute)}c.JSON(http.StatusOK, user)
}//其他方法类似
修改主函数初始化 Redis
cache.InitRedis()
配置环境变量
# 单节点模式配置
REDIS_MODE=single
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
REDIS_DB=0# 集群模式配置(覆盖单节点配置)
# REDIS_MODE=cluster
# REDIS_CLUSTER_ADDRESSES=192.168.1.1:6379,192.168.1.2:6379,192.168.1.3:6379
# REDIS_PASSWORD=