Кэширование
Проектирование и разработка распределенных программных систем, лекция 7
Кэширование
Запоминаем результаты обработки запросов, сохраняем их в быстрое хранилище, а затем отдаем уже вычисленные результаты в ответ на повторные запросы.
Кэширование
Несколько запросов к БД → 1 запрос к кэшу
Системы кэширования
Системы кэширования
И memcached, и Redis представляют собой хэш-таблицу, хранящую данные в оперативной памяти.
Алгоритм работы с кэшем
def get_data(query):
key = get_cache_key(query)
data = cache.get(key)
if not data:
data = get_data_from_db(query)
cache.set(key, data, ttl=5*60)
return data
Ключ кэширования
Ключ, по которому данные размещаются в хэш-таблице.
Ключ зависит от параметров запроса и должен вычисляться:
Ключ кэширования
region-74-type-hairdryer-power-1000-speed-1
Проблемы
Размер кэша
Разных вариантов фильтров может быть много, а размер кэша ограничен доступной оперативной памятью.
Что делать, когда кончается память
memcached: LRU eviction
Redis:
Стратегии eviction в Redis
Hit и Miss
Cache hit — из кэша удалось прочитать данные по ключу
Cache miss — данных по ключу в кэше не нашлось
Hit ratio — доля cache hit среди всех запросов к кэшу
Эффективность кэша
Пусть запрос в кэш занимает 20 мс, в базу — 100 мс.
Запрос с попаданием в кэш: 20 мс, с промахом: 120 мс.
Если количество промахов составляет:
Устаревание данных в кэше
Данные в БД обновились. Как обновить данные в кэше?
Инвалидация по времени
Ручная инвалидация
Сложно
Инвалидация с помощью тегов
Dogpile-эффект
В сервисе с большим трафиком после инвалидации ключа могут прийти сразу много запросов за данными по этому ключу.
Все эти запросы будут обслуживаться через БД, резко вырастет нагрузка.
В самом плохом случае запросы к БД будут таймаутить, и данные никогда не попадут в кэш.
Алгоритм работы с кэшем
def get_data(query):
key = get_cache_key(query)
data = cache.get(key)
if not data:
data = get_data_from_db(query)
cache.set(key, data, ttl=5*60)
return data
Решение проблемы dogpile
Прогрев кэша
При старте приложения может быть нужен прогрев кэша, чтобы он наполнился раньше, чем придут соответствующие запросы от пользователей.
Заключение
Кэш дает большой выигрыш в производительности, но очень легко сделать что-то не так и получить внезапную деградацию производительности или отображение устаревших данных (либо потратить много сил разработчиков на то, чтобы этого не произошло).
Поэтому применять кэширование нужно точечно и только там, где оно действительно нужно.
Ссылки
Ссылки