Как организовать кэширование для чтения переводов и записи изменений
Что проверяют
Понимаете ли вы, что переводы читаются в тысячи раз чаще, чем меняются, и умеете ли при этом не показывать пользователям старый текст после правки. Следом обычно спрашивают, как инвалидировать кэш, когда приложение запущено в нескольких процессах.
Как отвечать
Начните с профиля нагрузки и уровней кэша:
- кэш в процессе: словарь переводов для локали целиком в памяти,
cachetools.TTLCacheили обычныйdict. Самое быстрое чтение, без сети; - общий кэш: Redis, где бандл локали лежит одним хэшем (
HSET/HGETALL), а не тысячей ключей. Поход в Redis за каждой строкой интерфейса съест весь выигрыш сетевыми задержками; - источник правды: база, в которой переводы редактируют.
Для чтения подходит cache-aside: промах, загрузка из базы, запись в кэш с TTL. Для записи сначала коммит в базу, потом удаление ключа, а не перезапись: так меньше шансов, что параллельный запрос положит в кэш старую версию поверх новой. TTL остаётся страховкой на случай, если удаление не прошло.
Главная сложность это локальные кэши в каждом воркере Gunicorn или Uvicorn. Удобная схема: в Redis хранится номер версии переводов, при сохранении он растёт через INCR, а процессы раз в несколько секунд сверяют его и перезагружают бандл целиком. Альтернатива: рассылка инвалидации через Redis Pub/Sub.
Упомяните две детали. Одновременный промах сотен запросов бьёт по базе разом, поэтому загрузку защищают блокировкой, и бандл грузит один запрос. А cachetools сам по себе не потокобезопасен: в многопоточном коде передавайте lock=threading.Lock() в декоратор cached.
Где спотыкаются
Кэшируют каждую строку отдельным ключом в Redis. Страница с сотней подписей делает сотню сетевых запросов.
Держат кэш только в памяти процесса без механизма инвалидации. После правки перевода часть воркеров показывает новый текст, часть старый, и баг не воспроизводится стабильно.
Не кэшируют отсутствие перевода. Ключ, которого нет в базе, при каждом обращении снова уходит в базу, хотя ответ заранее известен: взять текст на языке по умолчанию.