Как оптимизировать нагрузку на Redis при проверке токенов в микросервисной архитектуре
Что проверяют
Понимаете ли вы, откуда берётся нагрузка: каждый сервис на каждый запрос ходит в Redis за одной и той же проверкой. Интервьюер ждёт не «поставим кэш перед кэшем», а архитектурного хода, который убирает лишние обращения совсем. Следом спрашивают, как тогда досрочно отозвать токен.
Как отвечать
Сначала выясните, какие токены: непрозрачные сессионные, данные которых лежат в Redis, или JWT, которые можно проверять без него.
- проверка на входе: токен валидирует API-шлюз или один auth-слой, а внутренние сервисы получают уже проверенную личность в заголовке или во внутреннем подписанном токене. Вместо проверки в каждом сервисе остаётся одна на запрос;
- JWT без похода в Redis: подпись и
expпроверяются локально черезPyJWTилиauthlib, публичные ключи берутся из JWKS и кэшируются в процессе,PyJWKClientделает это сам. Access-токен живёт от 5 до 15 минут; - отзыв: в Redis остаётся только denylist по
jtiс TTL, равным остатку жизни токена. Список маленький, и сверяться с ним можно на чувствительных операциях; - локальный кэш: результат проверки непрозрачного токена кладётся в
cachetools.TTLCacheна несколько секунд. Короткий TTL это компромисс между нагрузкой и скоростью отзыва. Для мгновенной инвалидации сервис отзыва шлёт событие через Pub/Sub, и экземпляры чистят свои кэши. Redis 6 и новее умеет client-side caching, когда сервер сам сообщает клиенту об изменении ключа; - сами обращения: один пул соединений на процесс в
redis.asyncio, а не подключение на запрос;MGETили pipeline для нескольких ключей; сессия в одном hash, а не в пяти ключах; - замеры:
INFO commandstats,SLOWLOG, латентность на стороне клиента. Часто упирается всё в число соединений или одну горячую команду, а не в CPU Redis.
Где спотыкаются
Предлагают кэшировать токены в Redis, когда проблема как раз в нагрузке на Redis.
Переходят на JWT и забывают про отзыв. Уволенный сотрудник работает до истечения токена, поэтому срок жизни должен быть коротким, а denylist обязателен.
Ставят локальный кэш на минуты без инвалидации. Разлогиненный пользователь продолжает ходить в систему, пока запись не протухнет.