Кэширование — широко освещаемая и известная тема.
Но в нем могут появиться и новые решения.
В частности, в сфере продуктов высокого уровня (например, в веб-разработке).
Столкнувшись с недостатками классического подхода, я попытался вывести идеальную схему кэширования для случая, когда релевантность данных не критична.
Тогда я попытался найти описание такой схемы, а еще лучше готовые решения.
Не нашел.
Поэтому я сам его и назвал — 2R2L (2 Range 2 Location) — двухдиапазонное двухдиапазонное «пространственное» кэширование.
Хотя наверняка где-то уже используется.
Все началось с простой задачи — показать пользователю новинки с учетом его индивидуальных предпочтений.
И если с получением новых товаров проблем не было, то сопоставление новых товаров с предпочтениями (анализ статистики) уже создавало заметную нагрузку (например, определим ее как 4 секунды).
Особенность задачи заключалась в том, что в качестве пользователей могли выступать целые организации.
Причем нередки случаи, когда на сервер одновременно (в течение 2-3 секунд) поступает 200-300 запросов, относящихся к одному пользователю.
Те.
один и тот же блок генерируется сразу для многих пользователей.
Очевидным решением является кэширование в оперативной памяти (мы не будем подвергать СУБД насилию, заставляя ее обрабатывать большой поток запросов).
Классическая схема:
- Запрос поступил
- Проверка кэша.
Если в нем есть данные и они не устарели, мы их просто отдаем.
- Нет данных => генерировать выходные данные
- Отправить пользователю
- Дополнительно добавляем в кеш с указанием TTL
И конечно же, все пользователи будут ждать «первого звонка».
Также учтите, что при отдельных значениях кэша количество записей может вырасти настолько, что доступной оперативной памяти сервера просто не хватит. Тогда представляется логичным использовать в качестве хранилища кэша локальный HDD-сервер.
Но мы сразу теряем скорость.
Как быть? Первое, что приходит на ум: было бы здорово хранить записи в 2-х местах - в оперативной памяти (часто запрашивается) и HDD (все или только редко запрашиваются).
Понятие «горячие и холодные данные» в чистом виде.
Существует множество реализаций этого подхода, поэтому мы не будем на нем останавливаться.
Давайте просто обозначим этот компонент как 2L. В моем случае он успешно реализован на базе СУБД Scylla. Но как избавиться от просадок, когда кэш устарел? И здесь мы подключаем концепцию 2R, смысл которой заключается в простой вещи: для записи в кэше нужно указать не 1 значение TTL, а 2. TTL1 — это временная метка, что означает «данные устарели, было бы его необходимо регенерировать, но его все равно можно использовать»; TTL2 — «все настолько устарело, что больше нельзя использовать».
Таким образом, мы получаем немного другую схему кэширования:
- Запрос поступил
- Ищем данные в кэше.
Если данные доступны и не устарели (t
- Данные есть, устаревшие, но можно использовать (TTL1 < t < TTL2) - we give it to the user AND initialize the cache entry update procedure
- Данных нет вообще (убивается после TTL2) — генерируем «как обычно» и записываем в кеш.
- После доставки контента пользователю или в параллельном потоке выполняем процедуры обновления записей кэша.
- если записи кэша используются достаточно часто, пользователь никогда не попадет в ситуацию «ожидания обновления кэша» — он всегда получит готовый результат.
- Если правильно организовать очередь «обновления», то можно гарантировать, что в случае нескольких одновременных обращений к записи с TTL1 < t < TTL2, there will be only 1 update task in the queue, and not several identical ones.
В простейшем случае PHP-код для реализации 2R может быть таким:
Теги: #программирование #php #кэширование$tmp = cache_get($key); If (!$tmp){
-
Нятый, Виллем Де
19 Oct, 24 -
Только Это
19 Oct, 24 -
Интернет-Расстояния
19 Oct, 24 -
Тестирование Пользовательского Интерфейса
19 Oct, 24 -
Следите За Твиттером
19 Oct, 24