Кеширование — это ответ!

…а какой был ваш вопрос?



Все любят кеши.

Упираетесь в БД по количеству запросов? Кеш!

Нужно быстрее отдавать данные? Кеш!



Но не все так просто.

В этом посте накидаю вопросов, на которые стоит ответить, если хотите добавить кеширующий слой.



1. Во-первых, кеш — это еще одна точка отказа.



Если кеш внешний, например Redis, то он вполне себе подвержен проблемам инфраструктурного характера: сеть, железки, «шумные соседи» на виртуалках, троттлинг отдельных компонентов по CPU.

А еще его нужно обслуживать: менять конфиги, обновлять с даунтаймом, …



Если ваше приложение уперлось в производительность БД, сможет ли оно выжить без кеша?

Как будете жить при недоступности Redis? Рейт-лимитер?

А насколько критично для потребителей получить отказ или задержку?



Если кеш in-memory, то как избежать повышенной нагрузки на БД при деплое?



Придется катить приложение очень медленно, канарейкой, поднимая новые поды пошагово.

Как гарантировать, что новый разработчик не задеплоит слишком быстро?



2. Во-вторых, кеш — это еще одно усложнение потоков данных.

Инвалидация кеша — одна из трёх главных проблем IT, после нейминга переменных и race condition.



Готово ли ваше приложение к eventual consistency?

В каких сценариях данные в БД меняются и когда инвалидировать кеш?



3. В-третьих, кеш — это доп. затраты на поддержку.

Допустим, через год появится ещё один сценарий изменения данных.

Как гарантировать, что новый разработчик не забудет инвалидировать кеш?

Опять же, сам редис и библиотеки надо обновлять.



4. В-четвёртых, кеш никогда не даёт 100% hit rate.

Придётся экспериментировать, какие данные кешировать, чтобы hit rate был хотя бы 80%+.



5. А точно ли кеш будет быстрее, чем в PgSQL?

Во всех современных БД есть встроенные механики кеширования, и умные люди долго их оттачивали.

Парочка пруфов: Can Postgres replace Redis as a cache? + Benchmark: Postgres as cache vs Redis



Наш пример:

— Есть PostgreSQL с 300 млн записей

— Есть хорошо оптимизированный запрос, который держит 2 млн RPM и отрабатывает за 8-10 мс в 99 перцентиле. Очевидно, это тайминги без похода на диск.

— Утилизация CPU на БД уже 60%+, поэтому вводим кеш для подстраховки от пиков



И что? Время ответа выросло до 20 мс!



————



К чему это я?

В большинстве случаев кеширование — очевидная, но не самая лучшая идея.

Это поможет как анастезия, но не решение корневой проблемы.



Более правильным решением будет расшивать БД:

— читать с реплики

— шардировать

— переезжать на другой тип СУБД, более подходящий под профиль нагрузки



Change my mind.