Когда говорят о кэшировании, для меня это тревожный знак. Да, я понимаю, что порой оно необходимо. Однако у меня возникает вопрос: понимает ли тот, кто говорит о кэшировании, весь набор проблем, что оно несет?

Напомню, что проблем с кэшем довольно много. Когда-то его нужно сбрасывать, когда-то — прогревать. Кэш должен быть транзакционным: если кто-то взялся его обновлять, другие клиенты должны ждать. Сюда же — проблема сериализации и походы в сеть.

Вместо сериализации я предпочитаю материализацию. Термин я взял из Постгреса, но его можно применить и к другим системам.

В Постгресе материализация работает так. Предположим, есть тяжелый запрос: много джоинов и сложных условий. Из него делают мат-вьюху и сбрасывают ее в таблицу по расписанию. Выборка из готовой таблицы быстрее на порядки. Важно, что эта таблица доступна всегда. Даже если мы не обновим вьюху, то все равно получим данные. Обновление вешают на крон или событие.

Другой пример: есть апишка, которая возвращает список отделений фирмы. Отделения появляются редко, поэтому ходить за ними в базу нет смысла. Проще выгрузить отделения в json-файл и раздавать его Nginx-ом. Задача выгрузки тоже ставится на крон.

Еще пример материализации — мой блог. Он устроен на Jekyll — генераторе статичных сайтов. При запуске Jekyll обходит md-файлы и производи файлы html. Далее они раздаются как статика; нет обращения к базе, Редису или очереди задач. Задачу обновления сайта — или материализации — обычно ставят на гит-хук или Github action, но я запускаю ее вручную. Таким образом собранный сайт есть всегда, пусть и с отставанием.

И еще пример: скажем, есть у вас в фирме тормозная CRM. Ее апишка держит не более полутора запросов в секунду и огорчает всех клиентов. Тут же находится обезьянка, которая предлагает Редис. А решение простое: реплицировать базу данных CRM в другую базу (частично или полностью). В реплицированной базе завести мат-вьюхи, которые собирают нужные проекции; вьюхи обновляются по крону. Даже если CRM отвалится, у вас будет копия базы, и что-то вы покажете. Может быть, данные будут не самые свежие, но это лучше, чем вечный спиннер или “попробуйте еще раз”.

Идея материализации в том, что данные есть всегда, и показать их очень легко. В идеале — прочитать файл или плоскую таблицу. Нет такого, что данные собираются по трем микросервисам, а потом еще обрабатываются. Наоборот — все готово, нужно только показать.

И есть фоновая задача, которая готовит данные: лезет в сервисы, очереди и другие малоприятные места. Эта задача отвечает за то, чтобы данные были актуальны. Если она отвалится, мы покажем устаревшие данные, что почти всегда лучше, чем свалиться с ошибкой.

Не всегда материализация полезна; возможно, она не решит какие-то из ваших задач. Но лично я рассматриваю ее как более разумный шаг по сравнению с кэшированием. Иногда материализация оказывается очень и очень в тему.