Кеширование — это ответ!
…а какой был ваш вопрос?
Все любят кеши.
Упираетесь в БД по количеству запросов? Кеш!
Нужно быстрее отдавать данные? Кеш!
Но не все так просто.
В этом посте накидаю вопросов, на которые стоит ответить, если хотите добавить кеширующий слой.
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.
…а какой был ваш вопрос?
Все любят кеши.
Упираетесь в БД по количеству запросов? Кеш!
Нужно быстрее отдавать данные? Кеш!
Но не все так просто.
В этом посте накидаю вопросов, на которые стоит ответить, если хотите добавить кеширующий слой.
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.