> Стоит ли кэшировать пустые результаты запросов к базе данных (Go)

Уровень: senior · Роль: backend · Категория: Технические вопросы

Компании: VK

Стек: Go

> Пример ответа

Да, кэшировать пустые результаты имеет смысл, но с осторожностью. Основная причина - защита от повторных дорогих запросов к БД, когда данные отсутствуют (например, поиск несуществующего пользователя по ID). В Go это часто реализуется через отдельный ключ с маркером пустоты (например, null или пустой слайс), чтобы отличить отсутствие данных от ошибки кэша.

Однако нужно учитывать:

  • TTL для пустых результатов должен быть коротким (секунды или минуты), иначе при появлении данных клиенты долго будут видеть пустоту.

  • Cache stampede - если пустой результат истекает одновременно у многих запросов, они могут одновременно ударить по БД. Решается через singleflight (например, golang.org/x/sync/singleflight).

  • Инвалидация - при вставке данных нужно удалять соответствующий пустой кэш.

Пример на Go с Redis:

GO
func GetUser(ctx context.Context, id string) (*User, error) {
key := "user:" + id
val, err := cache.Get(ctx, key).Result()
if err == nil {
if val == "" { // пустой маркер
return nil, nil
}
return deserialize(val)
}
// singleflight для защиты
result, err := group.Do(key, func() (interface{}, error) {
user, err := db.GetUser(id)
if err != nil {
return nil, err
}
if user == nil {
cache.Set(ctx, key, "", 30*time.Second) // короткий TTL
return nil, nil
}
cache.Set(ctx, key, serialize(user), 1*time.Hour)
return user, nil
})
if err != nil {
return nil, err
}
return result.(*User), nil
}

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

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью