Go 中的缓存:如何将应用加速 100 倍而不抓狂

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

为什么你的 Go 应用运行缓慢?很可能你忘了用缓存



你用 Go 编写了一个完美的应用。你为 goroutine、通道和快速的编译器感到自豪。但当负载达到 1000 RPS 时,一切开始变得卡顿。数据库崩溃,API 响应需要 5 秒,用户纷纷转向竞争对手。



熟悉这种情况吗?欢迎来到一个没有 Go 缓存 就寸步难行的世界。在本文中,我们将探讨如何将你的龟速应用变成猎豹。不掺水分,包含真实示例和现成的解决方案。



顺便说一下,我叫 Python,这里是 PythonLib。是的,我知道我们在讨论 Go。但好的代码不受语言界限的限制,我们撰写关于所有技术的有用文章。开始吧!



什么是缓存,为什么 Go 需要它?



数据缓存 是将频繁请求的数据保存在快速存储(内存、Redis、文件)中,以避免每次都去访问慢速数据源(数据库、外部 API、文件系统)。



Go 是一种用于高负载系统的语言。但即使是用 Go,如果不使用缓存,也可能写出慢速的应用。想象一下:你每秒从 PostgreSQL 查询国家列表 1000 次。与其对数据库进行 1000 次查询,不如只查询 1 次,其余 999 次从 Go 内存缓存 中提供数据。



结果:响应时间从 50 毫秒降至 0.5 毫秒。相差 100 倍。这不是魔法,这是合理的架构。



何时必须使用缓存?

  • 高负载(每秒 1000+ 请求)
  • 慢速的外部 API(支付、天气、汇率)
  • 繁重的计算(报告、分析)
  • 频繁查询的参考数据(城市列表、商品类别)


缓存策略:选择正确的方式



为了避免缓存变成反模式,你需要选择正确的 缓存策略。以下是在 Go 中有效的主要方案:



1. Cache-Aside(惰性缓存)

最流行的模式。应用首先检查缓存。如果没有数据(缓存未命中),则访问数据库,将结果保存到缓存,然后返回给客户端。



func GetUser(cache *redis.Client, db *sql.DB, userID int) (*User, error) {    // 尝试从缓存获取    val, err := cache.Get(ctx, "user:"+strconv.Itoa(userID)).Result()    if err == nil {        user := &User{}        json.Unmarshal([]byte(val), user)        return user, nil    }

// 缓存未命中——访问数据库 user, err := db.Query("SELECT * FROM users WHERE id = ?", userID) if err != nil { return nil, err }

// 保存到缓存,有效期 1 小时 data, _ := json.Marshal(user) cache.Set(ctx, "user:"+strconv.Itoa(userID), data, time.Hour)

return user, nil}


2. Write-Through(穿透写入)

数据同时写入缓存和数据库。优点:缓存始终是最新的。缺点:写入稍慢。



3. TTL(生存时间)

最简单的 缓存失效 方法。数据存活固定时间,之后自动删除。



// 缓存 5 分钟cache.Set(ctx, "key", value, 5*time.Minute)


在 Go 中手动实现内存缓存



有时你不想仅仅为了几个键而启动 Redis。对于这种情况,Go 内存缓存 非常合适。让我们编写一个简单但可用的版本:



package cache

import ( "sync" "time")

type Item struct { Value interface{} Expiration int64}

type Cache struct { items map[string]Item mu sync.RWMutex}

func New() *Cache { c := &Cache{ items: make(map[string]Item), } // 启动 goroutine 清理过期条目 go c.cleanup() return c}

func (c *Cache) Set(key string, value interface{}, ttl time.Duration) { c.mu.Lock() defer c.mu.Un

博客

书籍推荐