Ответ
Цели кэширования:
- Ускорение доступа – мгновенное получение часто используемых данных из быстрой памяти (RAM).
- Снижение нагрузки – уменьшение количества запросов к медленным источникам (БД, внешние API).
- Повышение отказоустойчивости – возможность обслуживать часть трафика при недоступности основного источника данных.
Типичные сценарии в Java:
- Кэширование результатов запросов к БД – избегание повторного выполнения идентичных SQL-запросов.
- Кэширование результатов вычислений – сохранение результатов ресурсоемких операций.
- Кэширование ответов внешних сервисов – снижение сетевых задержек и нагрузки на сторонние API.
Пример реализации с Caffeine:
Cache<Key, Value> cache = Caffeine.newBuilder()
.expireAfterWrite(10, TimeUnit.MINUTES) // Удаление через 10 минут после записи
.maximumSize(1000) // Ограничение по количеству записей
.build();
// Получение данных: если ключа нет в кэше, вызывается функция для его загрузки
Value value = cache.get(key, k -> loadValueFromDatabase(k));
Ключевые проблемы и решения:
- Согласованность данных (инвалидация) – необходимость актуализации или удаления устаревших данных при их изменении в источнике. Стратегии: TTL, явная инвалидация, write-through.
- Выбор политики вытеснения – какие данные удалять при заполнении кэша (LRU, LFU).
- Распределенное кэширование – синхронизация кэша между несколькими экземплярами приложения (например, с использованием Redis).