Кэширование в Go (Golang): Redis, групповое и in-memory кэширование

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Кэширование в Go (Golang): Redis и другие решения

Кэширование — один из ключевых инструментов для повышения производительности Go-приложений. Оно позволяет сократить время ответа, снизить нагрузку на базы данных и внешние API. В этой статье мы рассмотрим основные подходы к кэшированию в Go: использование Redis как внешнего хранилища, встроенное in-memory кэширование и групповое кэширование с помощью библиотеки groupcache.

1. Зачем нужно кэширование в Go?

Go — язык, ориентированный на высокую производительность, но даже самые быстрые запросы к БД или внешним сервисам могут стать узким местом. Кэширование помогает:

  • Уменьшить задержки при повторяющихся запросах.
  • Снизить нагрузку на базы данных и сторонние API.
  • Повысить пропускную способность сервера.
  • Сгладить пиковые нагрузки.

2. Redis — распределённое кэширование

Redis — наиболее популярное решение для внешнего кэша в Go. Он работает как in-memory хранилище с поддержкой TTL, персистентности и сложных структур данных.

Подключение Redis в Go

Для работы с Redis в Go чаще всего используется библиотека go-redis. Установка:

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

Пример: простое кэширование с TTL

package main

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

var ctx = context.Background()

func main() {
    rdb := redis.NewClient(&redis.Options{
        Addr: "localhost:6379",
    })

    // Устанавливаем значение с TTL 10 секунд
    err := rdb.Set(ctx, "user:42", `{"name":"Alice"}`, 10*time.Second).Err()
    if err != nil {
        panic(err)
    }

    // Получаем значение
    val, err := rdb.Get(ctx, "user:42").Result()
    if err != nil {
        fmt.Println("Кэш промах")
    } else {
        fmt.Println("Кэш попадание:", val)
    }
}

Стратегии инвалидации кэша в Redis

  • TTL (Time To Live) — автоматическое удаление по истечении времени.
  • Lazy-инвалидация — очистка кэша при обновлении данных.
  • Удаление по ключу — вызов DEL для конкретного ключа.
  • Паттерн "Cache-Aside" — приложение само управляет кэшем: сначала проверяет Redis, при промахе загружает из БД и сохраняет в кэш.

3. In-memory кэширование в Go

Для локального кэширования без внешних зависимостей можно использовать встроенные структуры Go или специализированные библиотеки.

Простой in-memory кэш с sync.Map

package main

import (
    "fmt"
    "sync"
    "time"
)

type CacheItem struct {
    Value      interface{}
    Expiration int64
}

type Cache struct {
    items sync.Map
}

func (c *Cache) Set(key string, value interface{}, ttl time.Duration) {
    c.items.Store(key, CacheItem{
        Value:      value,
        Expiration: time.Now().Add(ttl).UnixNano(),
    })
}

func (c *Cache) Get(key string) (interface{}, bool) {
    item, found := c.items.Load(key)
    if !found {
        return nil, false
    }
    cacheItem := item.(CacheItem)
    if time.Now().UnixNano() > cacheItem.Expiration {
        c.items.Delete(key)
        return nil, false
    }
    return cacheItem.Value, true
}

func main() {
    cache := &Cache{}
    cache.Set("key1", "value1", 5*time.Second)
    val, ok := cache.Get("key1")
    if ok {
        fmt.Println("Найдено:", val)
    }
}

Библиотека freecache

freecache — производительная in-memory библиотека с поддержкой TTL и низким потреблением памяти. Установка:

go get github.com/coocood/freecache
cache := freecache.NewCache(100 * 1024 * 1024) // 100 MB
cache.Set([]byte("key"), []byte("value"), 60)   // TTL 60 сек
val, err := cache.Get([]byte("key"))
if err != nil {
    fmt.Println("Промах")
} else {
    fmt.Println("Значение:", string(val))
}

4. Групповое кэширование с groupcache

groupcache — библиотека от Google, предназначенная для распределённого кэширования в Go. Она решает проблему "cache stampede" (кэш

Рекомендаций