Кэширование — это временное хранение данных в быстром хранилище (кэше). То есть мы запоминаем результат долгой операции (например, обращения в базу или на внешний API), чтобы в следующий раз не выполнять эту операцию заново, а быстро вернуть сохранённый результат.
Зачем используют кэши?
✅ Чтобы сократить время ответа на запрос
Если нужные данные есть в кэше, не нужно идти в базу/другой сервис — экономия времени.
✅ Чтобы сократить нагрузку от количества запросов
Если мы берем данные из кэша, то количество запросов к базе/другому сервису значительно снижается. Представьте на новостном портале написали про дополнительный выходной, и в базу начинают идти запросы на чтение этого поста от миллионов пользователей. Кэширование на разных уровнях поможет снизить эту нагрузку.
✅ Чтобы сократить вычислительную нагрузку
Представьте, что наш сервис рассчитывает график платежей для ипотеки. Мы заметили, что большая часть пользователей делает расчет для стандартных условий семейной ипотеки. Тогда мы можем закэшировать результаты расчета для этого случая и в случае совпадающих условий в запросе брать данные из кэша вместо запуска расчета каждый раз заново.
✅ Для защиты от кратковременных сбоев внешней системы
Например, в интернет-магазине данные для карточки товара могут собираться из нескольких источников: описание товара, цена, наличие/количество и др. Если сервис, в который мы ходили за описанием товара, вдруг отказал, то можно показывать описание из кэша вместо пустого описания. Конечно, это подходит не для всех ситуаций — например, для заказа товара нужно получить актуальные данные о его количестве, но в ряде ситуаций поможет не ухудшать пользовательский опыт.
Кэширование встречается на разных уровнях, например:
🔹В памяти самого микросервиса (HashMap или библиотека для in-memory кэширования)
🔹Во внешнем хранилище (Redis, Valkey, Memcached, Tarantool)
🔹На API Gateway
🔹На CDN (кэшируют контент ближе к пользователю)
🔹В браузере (статические ресурсы: картинки, скрипты)
Кэширование в памяти самого микросервиса используют для максимально быстрого получения данных. Работа со своей оперативной памятью и объектами своего языка будет быстрее любого похода по сети во внешний кэш.
Однако в случае падения микросервиса все данные из внутреннего кэша потеряются.
Если мы используем горизонтальное масштабирование, то есть поднимаем несколько копий микросервиса, то при использовании внутреннего кэша столкнемся с проблемами:
- нет единого места для инвалидации неактуальных данных
- растет потребление ресурсов у каждого микросервиса, возможно дублирование кэшируемых данных
Работа с внешним кэшем чуть медленнее из-за обращения к нему по сети, но он обладает следующими плюсами:
➕ Может использоваться несколькими сервисами сразу
➕ Удобен при горизонтальном масштабировании: не нужны sticky session, есть единая точка для инвалидации, нет дублирования
➕ Данные не теряются в случае падения микросервисов
➕ Удобно для прогрева
Есть понятие прогрева кэша — это первичное наполнение его данными. Смысл в том, что пустой кэш поначалу будет замедлять работу (попытка чтения из кэша, ах там пусто, тогда идём в БД). Поэтому кэши "прогревают", то есть заранее наполняют данными.
Если кэш в памяти микросервиса требует прогрева, то его придется прогревать заново при каждом рестарте микросервиса. Внешний кэш можно прогреть один раз, он не зависит от перезапусков микросервисов.
Продолжение ⬇️