Цель — снизить нагрузку на кластер PostgreSQL за счет кэширования частых запросов.
Однако я столкнулся со странной проблемой: после нескольких сотен запросов сервис начинает возвращать противоречивые данные — иногда значение кэша не соответствует последнему состоянию БД, а иногда кеш просто возвращает None даже несмотря на то, что ключ существует.
Вот упрощенный пример того, что я делаю:
Код: Выделить всё
from fastapi import FastAPI, Depends
from sqlalchemy.ext.asyncio import AsyncSession
from aioredis import Redis
import json
app = FastAPI()
async def get_user(user_id: int, db: AsyncSession, redis: Redis):
cache_key = f"user:{user_id}"
cached = await redis.get(cache_key)
if cached:
return json.loads(cached)
result = await db.execute("SELECT * FROM users WHERE id = :id", {"id": user_id})
user = result.fetchone()
if user:
await redis.set(cache_key, json.dumps(dict(user)), ex=60)
return user
При отладке я заметил, что противоречивые ответы в основном возникают во время одновременных запросов для одного и того же идентификатора пользователя.
Мне интересно:
Вызвано ли это конфликтом цикла событий Redis в асинхронном режиме?
Должно быть? Вместо этого я использую await redis.setex() или конвейер?
Или есть что-то в жизненном цикле асинхронного сеанса SQLAlchemy, что может привести к частичному чтению во время одновременного доступа?
Я прочитал документацию и попробовал и uvicorn, и Hypercorn, но проблема не устранена.
Кто-нибудь сталкивался с подобными проблемами рассинхронизации кэширования с асинхронными SQLAlchemy и aioredis в производстве?
Подробнее здесь: https://stackoverflow.com/questions/798 ... caching-wi
Мобильная версия