Какие существуют стратегии кэширования? Опишите их плюсы и минусы.

Ответ

Существует несколько основных стратегий кэширования, каждая со своими компромиссами. Выбор зависит от требований к консистентности данных, производительности и сложности реализации.

1. Cache-Aside (Lazy Loading / Ленивая загрузка)

Это самая распространенная и простая в реализации стратегия.

Как работает:

  1. Приложение запрашивает данные сначала из кэша.
  2. Cache miss (промах): Если данных в кэше нет, приложение читает их из основной базы данных (БД).
  3. Затем приложение сохраняет эти данные в кэш для будущих запросов.
  4. Приложение возвращает данные.
  • Плюсы:
    • Простота реализации.
    • Кэшируются только те данные, которые реально запрашиваются.
    • Устойчивость к падению кэша (приложение продолжит работать, хотя и медленнее).
  • Минусы:
    • Cache miss penalty: Первый запрос на получение данных всегда будет медленным.
    • Возможна неконсистентность данных, если данные в БД обновились, а кэш не был инвалидирован.

Пример на Go (стратегия Cache-Aside):

// GetUser пытается получить пользователя из кэша, при неудаче - из БД.
func GetUser(db *sql.DB, cache *redis.Client, userID string) (*User, error) {
    // 1. Пытаемся получить из кэша
    cachedData, err := cache.Get(ctx, "user:"+userID).Bytes()
    if err == nil {
        // Cache hit: данные найдены в кэше
        var user User
        json.Unmarshal(cachedData, &user)
        return &user, nil
    }

    // 2. Cache miss: получаем из БД
    var user User
    err = db.QueryRow("SELECT id, name FROM users WHERE id = ?", userID).Scan(&user.ID, &user.Name)
    if err != nil {
        return nil, err
    }

    // 3. Сохраняем в кэш на будущее
    userJSON, _ := json.Marshal(user)
    // Устанавливаем TTL (Time-To-Live), чтобы кэш не устаревал вечно
    cache.Set(ctx, "user:"+userID, userJSON, time.Hour)

    return &user, nil
}

2. Write-Through (Сквозная запись)

  • Как работает: Приложение всегда пишет данные одновременно и в кэш, и в БД. Запись считается успешной только после подтверждения от обоих хранилищ.
  • Плюсы: Высокая консистентность данных между кэшем и БД.
  • Минусы: Увеличивается задержка операции записи (write latency), так как нужно дождаться ответа от двух систем.

3. Write-Back (Отложенная запись)

  • Как работает: Приложение пишет данные только в кэш, который отвечает немедленно. Спустя некоторое время или по накоплению определенного объема данных, кэш асинхронно записывает их в БД.
  • Плюсы: Очень низкая задержка и высокая пропускная способность операций записи.
  • Минусы: Высокий риск потери данных, если кэш выйдет из строя до того, как данные будут сохранены в БД.