Кэширование через Redis
Relevant source files
The following files were used as context for generating this wiki page:
Система кэширования в проекте Music Service реализована на базе Redis и предназначена для снижения нагрузки на основную реляционную базу данных (PostgreSQL), а также для управления временными бизнес-ограничениями, такими как лимиты прослушивания для пользователей с бесплатной подпиской.
Кэширование охватывает два основных аспекта: абстрактный слой для хранения и извлечения сериализованных данных объектов (например, треков) и использование Redis как хранилища счетчиков для реализации логики лимитов (Rate Limiting/Quota Management).
Архитектура системы кэширования
Система строится на использовании официального клиента go-redis/v9. В приложении выделен отдельный слой internal/core/redis, который предоставляет обертки для базовых операций Redis.
Компоненты системы
| Компонент | Файл | Описание |
|---|---|---|
| Redis Client | internal/core/redis/redis.go | Инициализация и проверка соединения (Ping) с сервером Redis. |
| Cache Wrapper | internal/core/redis/cache.go | Высокоуровневая обертка для работы с JSON-сериализованными данными. |
| Config | internal/core/config/config.go | Управление параметрами подключения и лимитами через переменные окружения. |
| Track Service | internal/features/tracks/service/ | Пример бизнес-логики, использующей кэш для управления лимитами и инвалидации данных. |
Sources: internal/core/redis/redis.go, internal/core/redis/cache.go, cmd/app/main.go:81-87
Схема взаимодействия компонентов
Ниже представлена диаграмма процесса инициализации и использования кэша в приложении.
Реализация Cache Wrapper
Слой кэширования предоставляет три основных метода для работы с данными, автоматически обрабатывая сериализацию в JSON.
Основные методы Cache структур
- Get(ctx, key, dest): Извлекает строковое значение из Redis и выполняет
json.Unmarshalв переданный объект. Возвращаетfalse, nil, если ключ не найден. - Set(ctx, key, value, ttl): Выполняет
json.Marshalобъекта и сохраняет его в Redis с указанным временем жизни (TTL). - Delete(ctx, key): Удаляет ключ из хранилища. Используется при обновлении данных для обеспечения консистентности.
func (c *Cache) Get(ctx context.Context, key string, dest any) (bool, error) {
val, err := c.client.Get(ctx, key).Result()
if err == redis.Nil {
return false, nil
}
// ... unmarshal logic
err = json.Unmarshal([]byte(val), dest)
return true, nil
}
Sources: internal/core/redis/cache.go:19-58
Кэширование в бизнес-логике
Управление лимитами прослушивания
Redis используется напрямую (через redis.Client) в TrackService для подсчета количества прослушанных треков пользователями с ролью FREE. Это позволяет быстро проверять дневную квоту без выполнения тяжелых COUNT запросов к PostgreSQL.
Инвалидация кэша
При обновлении информации о треке администратором, система выполняет принудительное удаление закэшированной версии объекта, чтобы гарантировать актуальность данных при следующем запросе.
func (s *TrackService) Update(ctx context.Context, t *model.Track) (*model.Track, error) {
// Инвалидация кэша перед обновлением в БД
_ = s.cache.Delete(ctx, fmt.Sprintf("track:%d", t.ID))
updated, err := s.repo.Update(ctx, t)
return updated, err
}
Sources: internal/features/tracks/service/update.go:13-15
Конфигурация и развертывание
Параметры подключения к Redis задаются через переменные окружения и обрабатываются в модуле конфигурации.
Параметры конфигурации
| Переменная | Значение по умолчанию | Описание |
|---|---|---|
REDIS_HOST | localhost | Адрес сервера Redis. |
REDIS_PORT | 6379 | Порт сервера Redis. |
REDIS_PASSWORD | "" | Пароль для аутентификации. |
Sources: internal/core/config/config.go:37-39
Docker Compose
Для локальной разработки и тестирования используется официальный образ redis:7-alpine. Для обеспечения доступности сервиса используется healthcheck с командой redis-cli ping.
redis:
image: redis:7-alpine
container_name: music-redis
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 5s
timeout: 5s
retries: 5
Sources: docker-compose.yml:45-54
Заключение
Использование Redis в проекте позволяет эффективно решать задачи как классического кэширования объектов (черый слой Cache), так и оперативного управления бизнес-метриками (лимиты прослушивания). Благодаря централизованной инициализации в main.go и внедрению зависимостей в сервисы, обеспечивается гибкость настройки и простота тестирования системы кэширования.