[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"question-keshirovanie-kakie-strategii-invalidatsii-kesha-sushchestvuyut":3},{"id":4,"slug":5,"topicId":6,"topicSlug":7,"topicName":8,"topicEmoji":9,"question":10,"answer":11,"codeLang":12,"codeSrc":12,"important":12,"commonMistakes":12,"modernUsage":12,"difficulty":13,"tags":14,"related":21,"progress":22,"seo":23},183,"kakie-strategii-invalidatsii-kesha-sushchestvuyut",5,"keshirovanie","Кеширование","⚡","Какие стратегии инвалидации кэша существуют?","Инвалидация кэша — это процесс удаления или обновления устаревших данных в кэше, являющийся самой сложной частью кэширования.\n\n> **Аналогия из жизни:** инвалидация кэша — как обновление расписания на информационном стенде. Если расписание изменилось, но стенд не обновили, люди будут приходить в неправильное время. Вопрос в том, как и когда обновлять стенд.\n\n### 1. TTL (Time-To-Live)\n\nСамая простая стратегия — данные автоматически удаляются через заданное время.\n\n```java\n@Cacheable(value = \"users\", key = \"#id\") \u002F\u002F TTL задаётся в конфигурации CacheManager\npublic User findById(Long id) { ... }\n```\n\n```bash\nSET user:1 '{\"name\":\"John\"}' EX 600  # удалится через 10 минут\n```\n\n**Плюсы:** простота; гарантия, что данные не старше TTL.\n**Минусы:** в пределах TTL данные могут быть устаревшими; после TTL — cache miss.\n\n### 2. Явная инвалидация (Event-Driven)\n\nПри обновлении данных явно удаляем\u002Fобновляем кэш.\n\n```java\n@CacheEvict(value = \"users\", key = \"#id\")\npublic void updateUser(Long id, UpdateRequest request) {\n    userRepository.save(toEntity(id, request));\n}\n\n\u002F\u002F Или через события (в микросервисах)\n@TransactionalEventListener\npublic void onUserUpdated(UserUpdatedEvent event) {\n    cacheManager.getCache(\"users\").evict(event.getUserId());\n}\n```\n\n**В микросервисах** сервис публикует событие в Kafka, потребители инвалидируют свои кэши:\n\n\u003Cdetails>\u003Csummary>Пример кода\u003C\u002Fsummary>\n\n```java\n\u002F\u002F Сервис A: обновил пользователя → опубликовал событие\n@Transactional\npublic void updateUser(Long id, UpdateRequest request) {\n    userRepository.save(toEntity(id, request));\n    kafkaTemplate.send(\"user-events\", new UserUpdatedEvent(id));\n}\n\n\u002F\u002F Сервис B: получил событие → инвалидировал свой кэш\n@KafkaListener(topics = \"user-events\")\npublic void onUserEvent(UserUpdatedEvent event) {\n    cacheManager.getCache(\"users\").evict(event.getUserId());\n}\n```\n\n\u003C\u002Fdetails>\n\n### 3. Write-Through \u002F Write-Behind\n\nКэш обновляется одновременно с БД (Write-Through) или асинхронно (Write-Behind). Подробнее см. раздел \"Паттерны кэширования\".\n\n### 4. Version-based (ETag)\n\nКаждая запись имеет версию. При чтении из кэша проверяется, не изменилась ли версия в БД.\n\n```java\n\u002F\u002F Быстрая проверка версии (один лёгкий запрос к БД)\nLong cachedVersion = cache.get(\"user:\" + id + \":version\");\nLong currentVersion = userRepository.getVersion(id);\nif (!currentVersion.equals(cachedVersion)) {\n    \u002F\u002F Версия изменилась — обновить кэш\n    cache.put(\"user:\" + id, userRepository.findById(id));\n    cache.put(\"user:\" + id + \":version\", currentVersion);\n}\n```\n\n### 5. Pub\u002FSub-инвалидация (для распределённых кэшей)\n\nRedis Pub\u002FSub для уведомления всех экземпляров приложения:\n\n```java\n\u002F\u002F При обновлении — публикуем в канал\nredisTemplate.convertAndSend(\"cache-invalidation\", \"users:\" + id);\n\n\u002F\u002F Все экземпляры слушают канал\n@Component\npublic class CacheInvalidationListener implements MessageListener {\n    @Override\n    public void onMessage(Message message, byte[] pattern) {\n        String key = new String(message.getBody());\n        caffeineCache.invalidate(key); \u002F\u002F инвалидируем L1 (in-memory)\n    }\n}\n```\n\n### Сравнение стратегий\n\n| Стратегия | Согласованность | Сложность | Применение |\n|-----------|----------------|-----------|------------|\n| TTL | Eventual (в пределах TTL) | Низкая | Справочники, каталоги |\n| Явная инвалидация | Высокая | Средняя | CRUD-операции |\n| Event-driven (Kafka) | Eventual | Высокая | Микросервисы |\n| Write-Through | Strong | Средняя | Критичные данные |\n| Version-based | Strong | Средняя | Когда TTL неприемлем |\n\n### Выводы\n\n- **TTL + явная инвалидация** — наиболее распространённая комбинация: TTL как страховка, `@CacheEvict` при обновлении\n- В микросервисах: событийная инвалидация через Kafka\u002FRedis Pub\u002FSub\n- Стратегия \"cache aside + TTL + evict on update\" покрывает 90% сценариев\n\n### Частые ошибки\n\n- **Обновить БД, забыть инвалидировать кэш** — пользователи видят старые данные\n- **Инвалидировать кэш ДО записи в БД** — при ошибке записи кэш пуст, следующий запрос загрузит старые данные из БД\n- **Правильный порядок: сначала запись в БД, потом инвалидация кэша**\n- **TTL слишком большой** — 24 часа для профиля пользователя = показывать вчерашнее имя\n- **TTL слишком маленький** — 1 секунда для справочника = нет смысла кэшировать\n\n### Как используется в 2026\n\n- TTL + `@CacheEvict` — стандарт в Spring-приложениях\n- Kafka-based инвалидация — стандарт в микросервисах\n- Redis keyspace notifications — автоматическое уведомление об истечении TTL\n\n> **На собеседовании:** интервьюер хочет услышать про комбинацию TTL + явная инвалидация и правильный порядок операций (сначала БД, потом кэш). Частая ошибка — не знать про event-driven инвалидацию в микросервисах.","","middle",[15,16,17,18,19,20],"invalidation","event-driven","etag","pub-sub","caching","ttl",[],null,{"title":24,"description":25,"ogTitle":26,"ogDescription":27,"keywords":28,"schemaAnswer":38,"featuredSnippetReady":39},"Какие стратегии инвалидации кэша существуют — Gymterview","Стратегии инвалидации кэша: TTL, явная инвалидация, Event-Driven (Kafka), Write-Through, Version-based (ETag), Pub\u002FSub. Сравнение и типичные ошибки.","Стратегии инвалидации кэша: TTL, Event-Driven, Pub\u002FSub — Gymterview","Обзор стратегий инвалидации кэша с примерами на Spring и Kafka. TTL + явная инвалидация покрывают 90% сценариев.",[29,30,31,32,33,34,35,36,37],"инвалидация кэша","cache invalidation","TTL","CacheEvict","Kafka","Pub\u002FSub","ETag","Write-Through","Spring Cache","Основные стратегии: TTL (автоматическое удаление по времени), явная инвалидация (@CacheEvict при обновлении), Event-driven через Kafka (для микросервисов), Write-Through (кэш обновляется синхронно с БД), Version-based\u002FETag (проверка версии), Pub\u002FSub (Redis уведомления всех экземпляров). Комбинация TTL + явная инвалидация — наиболее распространённый подход.",true]