// личный канал‑лог
gavrilovlog
← все записи

Стратегия кэширования на прокси сервисе

👁 5164
При проектировании прокси сервиса, который получает балансы с некого провайдера мы стали зависимыми от работоспособности этого провайдера. И для того чтобы иметь возможность всегда отдавать пользователям данные по их портфелю, мы должны как-то сохранять на своей стороне результаты запросов от провайдера, так как если провайдер становится недоступным, мы всегда должны иметь возможность использовать сохраненные данные и вернуть их пользователю. При этом у нас должен быть механизм кэширования, чтобы с нашего сервиса не улетали бесчисленное множество запросов пользователей и чтобы мы не провалились по 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