Ответ
Проблема «пустого кэша» возникает, когда каждый экземпляр сервиса имеет свой изолированный локальный кэш. Решение — использовать распределенный (общий) кэш или стратегию инвалидации.
Основные подходы:
-
Внешнее распределенное хранилище кэша (Рекомендуется). Все экземпляры сервиса подключаются к одному кэш-серверу.
- Redis: Самый популярный вариант. Spring Boot поддерживает через
spring-boot-starter-data-redis.// application.properties spring.cache.type=redis spring.redis.host=shared-redis
// Конфигурация @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { return RedisCacheManager.create(factory); }
- **Memcached, Hazelcast, Apache Ignite.** - Redis: Самый популярный вариант. Spring Boot поддерживает через
-
Событийная синхронизация (Cache Invalidation). При обновлении данных в одном экземпляре он рассылает событие другим для очистки (evict) их локального кэша. Можно использовать брокеры сообщений (Kafka, RabbitMQ) или Spring Cloud Bus.
-
Стратегия «Write-Through» / «Cache-Aside» с общей БД. Кэш используется только для чтения. Запись всегда идет в основную базу данных. При этом:
- Устанавливается короткий TTL (Time To Live) для записей кэша, чтобы данные периодически обновлялись.
- Используется общая БД как источник истины. Риск: кратковременная несогласованность (пока TTL не истек).
-
Клиентские библиотеки с распределенной поддержкой. Например, Caffeine + JCache (JSR-107) провайдер, такой как Hazelcast, который может автоматически реплицировать изменения кэша между узлами.
Практический совет: Для большинства микросервисных архитектур Redis является стандартным выбором для распределенного кэширования из-за простоты, производительности и широкой поддержки.
Ответ 18+ 🔞
А, слушай, вот эта классика, блядь! Пустой кэш, когда каждый экземпляр сервиса сам по себе, как сука, в своём углу сидит. У одного в кэше есть, у другого — нихуя, и пошла пляска с бубном. Знакомо, да? Это ж как в коммуналке: один холодильник купил, а второй на него с голодухи смотрит.
Так вот, чтобы не было этой ебли, нужно либо всем в один общий холодильник лазить, либо договориться, когда кто-то колбасу съел, всем об этом кричать.
Основные заходы, блядь:
-
Внешний распределённый кэш (Идеальный вариант, ёпта). Все твои инстансы тычутся в один и тот же кэш-сервер, как мухи в мёд. Нет больше проблем.
- Redis: Царь и бог, все его юзают. Spring Boot его из коробки жуёт.
// application.properties spring.cache.type=redis spring.redis.host=shared-redis // Вот сюда все и ходят
// Конфигурация @Bean public CacheManager cacheManager(RedisConnectionFactory factory) { return RedisCacheManager.create(factory); // И всё, магия началась }
- **Memcached, Hazelcast и прочие:** Тоже годнота, но Redis — это как мерседес в мире тачек, блядь. - Redis: Царь и бог, все его юзают. Spring Boot его из коробки жуёт.
-
Синхронизация через события (Инвалидация кэша). Один экземпляр что-то обновил — и сразу орёт на всю деревню: «Эй, пидарасы, у себя в кэше эту хуйню выкидывайте!». Можно через Kafka или RabbitMQ эту весть разносить. Работает, но мороки — овердохуища.
-
Стратегия «Пиши в базу, читай откуда попало». Запись всегда идёт в главную базу — это наш источник истины, блядь. А кэш живёт своей жизнью, но с коротким сроком годности (TTL). Минус в том, что может быть рассинхрон на пару секунд, пока кэш не протухет. Но иногда и так сойдёт, если не перфекционист, ебать.
-
Умные клиентские библиотеки. Берёшь что-то вроде Caffeine, но подключаешь к нему Hazelcast, который сам, хитрая жопа, будет разгребать кэши между узлами. Почти магия, но нужно знать, что ты делаешь, а то наебнёшься.
А теперь практический совет, который всем похуй, но я скажу: В 90% случаев бери Redis и не еби себе мозг. Это стандарт де-факто, работает как швейцарские часы, и документации — просто завались. Не надо изобретать хуй в пальто, когда всё уже придумано.