Назад к вопросам
Senior
6
Что такое cache stampede и cache penetration? Как с ними бороться?
Компании, где спрашивали
прайм пейментс
Ответ от нейросети
sobes.tech AI
Cache stampede — ситуация, когда множество запросов одновременно пытаются получить данные из кеша, но при этом кеш пуст или устарел, и все эти запросы начинают одновременно обращаться к медленному источнику данных (например, базе), создавая нагрузку.
Cache penetration — ситуация, когда запросы постоянно обращаются к кешу с ключами, которых там нет (например, из-за отсутствия данных в базе), и каждый такой запрос приводит к обращению к базе, что может привести к перегрузке.
Как бороться:
Cache stampede:
- Использовать механизм блокировки (mutex) при обновлении кеша: первый запрос обновляет кеш, остальные ждут.
- Применять стратегию "early recomputation" — обновлять кеш до истечения срока жизни.
- Использовать "probabilistic early expiration" — обновлять кеш с вероятностью до истечения TTL.
Cache penetration:
- Кешировать отрицательные результаты (например, пустые или null значения) с коротким TTL, чтобы не обращаться к базе повторно.
- Валидировать входные данные, чтобы не допускать запросов с некорректными ключами.
- Использовать фильтры (например, Bloom filter) для предварительной проверки наличия ключа в базе.
Пример на Java с использованием блокировки для cache stampede:
private final ConcurrentHashMap<String, Object> cache = new ConcurrentHashMap<>();
private final ConcurrentHashMap<String, ReentrantLock> locks = new ConcurrentHashMap<>();
public Object getData(String key) {
Object value = cache.get(key);
if (value != null) return value;
ReentrantLock lock = locks.computeIfAbsent(key, k -> new ReentrantLock());
lock.lock();
try {
// повторная проверка после захвата блокировки
value = cache.get(key);
if (value == null) {
value = loadFromDb(key); // медленная операция
cache.put(key, value != null ? value : NULL_PLACEHOLDER);
}
return value == NULL_PLACEHOLDER ? null : value;
} finally {
lock.unlock();
}
}
Такой подход помогает избежать одновременного обращения к базе при отсутствии кеша.