Стратегия кэширования на прокси сервисе
👁 516↗ 4
При проектировании прокси сервиса, который получает балансы с некого провайдера мы стали зависимыми от работоспособности этого провайдера.
И для того чтобы иметь возможность всегда отдавать пользователям данные по их портфелю, мы должны как-то сохранять на своей стороне результаты запросов от провайдера, так как если провайдер становится недоступным, мы всегда должны иметь возможность использовать сохраненные данные и вернуть их пользователю.
При этом у нас должен быть механизм кэширования, чтобы с нашего сервиса не улетали бесчисленное множество запросов пользователей и чтобы мы не провалились по Rate Limits.
Для решения этих задач существует огромное количество стратегий кэширования, такие как: «Cache through», «Cache aside», «Cache with Expiry», «Stale Fallback» и другие.
Однако иногда решение требует комбинировать различные компоненты таких стратегий, так и в текущей задаче я предлагаю вам рассмотреть следующий вариант.
Для начала, как работает обычное кэширование.
Когда пользователь зашел на сервис и сделал запрос баланса, мы делаем запрос на провайдер, сохраняем полученные данные в кэше например TTL=15 и в течении следующих 15 секунд все запросы будут возвращаться из редиса, а по истечению этих 15 секунд пользовательский запрос уходит на провайдер и снова записывается в редис ответ провайдера.
Но что делать если провайдер будет недоступен в какой-то момент, так как нам в любом случае надо что-то вернуть пользователю. Поэтому мы всегда должны сохранять данные в редис без TTL, что значит на вечно. Но тогда у нас нет механики кэширования, так как данные всегда будут возвращаться из Редиса. И нам потребуется иметь какой-то фоновый процесс обновления кэша.
Чтобы решить это, мы объединили стратегии «Cache with Expiry» и «Stale Fallback» за счет того что мы записываем помимо ответа от провайдера, еще один ключ, так называемый «флаг». Это может быть просто булево значение. И при записи этого флага указать TTL = 15 секунд. Выглядит это так, что вместо одного «ключ-значения» мы записываем два, где одна из записей является обычным флагом true.
В таком варианте происходит следующий алгоритм:*
1. Проверяем наличие флага в редисе.
2. Если есть, то отдаем данные из редиса.
3. Если нет, то идем в провайдер за этими данными.
4. Если данные пришли от провайдера, то обновляем их в редисе и дополнительно записываем флаг с TTL = 15 секунд.
5. Если провайдер недоступен, то просто отдаем данные из редиса.
Итог, пользователь всегда будет получать данные, но немного неактуальные из-за кэширования или в случае недоступности провайдера, однако это более юзерфрендли, чем вернуть пустой ответ или ошибку 400 ~ 500.
#SoftwareArchitecture #Backend
Канал: @knowyourbackend
Чат: @kyb_chat
411