Cache-Aside
Приложение управляет кэшем само
В Cache-Aside кэш находится рядом с основным хранилищем, но приложение само решает, когда читать из него и когда обращаться к источнику данных.
Для чтения схема обычно выглядит так: сначала ищем значение в кэше. При hit сразу возвращаем его. При miss читаем основной источник, кладём полученный результат в кэш и только затем отвечаем.
Product getProduct(long id) {
String key = "product:" + id;
Product product = cache.get(key);
if (product != null) {
return product;
}
product = repository.findById(id);
cache.put(key, product);
return product;
}
Почему эта схема популярна
Cache-Aside не требует, чтобы кэш умел самостоятельно работать с базой данных. Приложение контролирует ключи, формат значения и момент заполнения, поэтому схему легко добавить вокруг уже существующего чтения.
В кэш попадают только реально запрошенные данные. Если объект никто не читает, память на него не тратится.
Промах всё равно стоит дорого
Первый запрос к отсутствующему ключу проходит полный путь до основного источника, поэтому его latency не становится меньше. После заполнения ускоряются уже следующие чтения.
Если много запросов одновременно промахнутся по одному популярному ключу, они могут почти одновременно отправиться к основному хранилищу. Это важно учитывать для данных, которые резко становятся популярными.
Изменение данных требует отдельного решения
Cache-Aside описывает прежде всего путь чтения. После изменения данных приложение должно сделать так, чтобы старая копия не оставалась в кэше бесконечно. Конкретные способы обновления и удаления устаревших значений разберём отдельно в теме об инвалидации.