digital-garden/dev/architecture/highload/Инвалидация кэша.md

64 lines
4.1 KiB
Markdown
Raw Normal View History

2024-09-11 21:28:43 +03:00
---
aliases:
- инвалидации кэша
tags:
- maturity/🌱
date:
- - 2024-06-18
zero-link:
- "[[../../../meta/zero/00 HighLoad|00 HighLoad]]"
parents:
- "[[../Кэширование|Кэширование]]"
linked:
---
Если мы закэшировали какие-то данные, например, выборку из БД, рано или поздно исходные данные изменяются, и кэш перестает быть валидным. Причем очень желательно, чтобы кэш сбрасывался сразу же за изменением.
**Способы инвалидации:**
- Задать срок жизни - TTL.
- Самая простая реализация.
- При малом TTL будет высокий [CacheMissRate](CacheMissRate.md)
- При большом TTL данные могут быть не консистентны
- Инвалидация по событию
- Удаляем старые данные при изменении в базе или по событию от кафки.
- Опасно из-за риска мгновенной инвалидации и сопутствующей [[Перестройка кэша|перестройки кэша]]
- Использование [[../../algorithm/Алгоритмы вытеснения|алгоритмов вытеснения]]
2024-09-13 07:09:47 +03:00
Дополнительно для работы со статическими файлами можно отменить [[../Fingerprint|Fingerprint]].
2024-09-11 21:28:43 +03:00
## Инвалидация по TTL
Один из подходов это инвалидация по времени. Для кэшированных данных устанавливается TTL, и по прошествию времени кэш удаляется. Такое вариант подходит для редко изменяемых данных, устаревание которых не приводит к серьезным проблемам в бизнес-логике, например словари.
2024-09-11 21:28:43 +03:00
При таком варианте важно подобрать оптимальное время жизни кэша, слишком маленькое время жизни будет давать плохую производительность, слишком большое ухудшит опыт пользователей. В оценке эффективности кэша поможет метрика [[CacheMissRate]].
Если просто установить TTL, то спустя какое-то время он истечет и данные будут удалены, но что если к ним постоянно обращаются. В некоторых случаях я использую подход, при котором при запросе данных из кэша проверяется оставшийся TTL, и если он меньше, чем некоторое значение, то TTL устанавливается заново.
Данные остаются в кэше, если ими активно пользуются. В таком случае при обновлении данных, необходимо вручную положить новые данные или инвалидировать кэш по событиям.
```lua
local key = KEYS[1];
local threshold = tonumber(ARGV[1]);
local new_ttl = tonumber(ARGV[2]);
local value = redis.call('get', key);
if value then
local ttl = redis.call('pttl', key);
if ttl >= 0 and ttl <= threshold then
redis.call('pexpire', key, new_ttl);
end;
end;
return value;
```
2024-09-11 21:28:43 +03:00
***
## Мета информация
**Область**:: [[../../../meta/zero/00 HighLoad|00 HighLoad]]
**Родитель**:: [[../Кэширование|Кэширование]]
**Источник**::
**Автор**::
**Создана**:: [[2024-06-18]]
### Дополнительные материалы
-
### Дочерние заметки
```dataview
LIST
FROM [[]]
WHERE contains(Родитель, this.file.link) or contains(parents, this.file.link)
```