Наиболее надёжная стратегия - Cache-Aside с инвалидацией через удаление (при записи удалять ключ из кеша, а не обновлять его).
При обновлении кеша возможна гонка: два запроса читают устаревшие данные из БД и оба пишут в кеш. При удалении следующий чтение промахнется по кешу и загрузит актуальные данные из БД, затем заполнит кеш.
// Чтение
val, err := cache.Get(ctx, key)
if err == redis.Nil {
val, err = db.Get(ctx, key)
if err != nil { return err }
cache.Set(ctx, key, val, ttl)
}
return val, nil
// Запись
if err := db.Set(ctx, key, newVal); err != nil { return err }
cache.Del(ctx, key) // удалить, не обновлять
Так при любом сбое (например, запись в кеш не удалась) следующее чтение получит свежие данные из БД.