Тяжелое кэширование

admin

При кэшировании особо тяжелых запросов, которые выполняются более нескольких секунд, может возникнуть большая проблема. Если время кэша подойдет к концу, таких тяжелых запросов может быть выполнено сразу несколько, а не один. Например:


memcache_connect('localhost', 11211);

if ( !$list = memcache_get(‘user_ages’) )

{

**$sql = ‘SELET count(*), age FROM users GROUP BY age’;**

$q = mysql_query($sql);

while ($row = mysql_fetch_assoc($q)) $list[] = $row;

memcache_set(‘user_ages’, $list, 60*60);

}

## Обычное кэширование тяжелого запроса с помощью Memcache

Представим, что такой SQL запрос будет выполняться 10 секунд. Если в кэше ничего не будет, то первый вызов приведет к тому, что будет выполнен выделенный код:

memcache_connect('localhost', 11211);

if ( !$list = memcache_get(‘user_ages’) )

{

**$sql = ‘SELET count(*), age FROM users GROUP BY age’;

$q = mysql_query($sql);

while ($row = mysql_fetch_assoc($q)) $list[] = $row;

memcache_set(‘user_ages’, $list, 60*60);**

}

## Пройдет 10 секунд с начала запроса до сохранения результата в кэш

Пройдет 10 секунд до того момента, как результат запроса будет сохранен в кэш. Это значит, что в течение 10 секунд любое посещение страницы с этим запросом будет выполнять SQL запрос (т.к. в кэше еще ничего не будет). Это может привести к катастрофическим последствиям, если это происходит в час пик. Каждый новый запрос будет замедлять выполнение предыдущего, т.к. нагрузка на базу будет расти.

Решение

[ad]

Чтобы избавиться от подобных проблем, необходимо использовать методику дублирования ключей. Для каждого тяжелого запроса создается не один, а два ключа:

  • Основной ключ. После выполнения запроса сюда сохраняется результат со стандартным ttl (в примере: 1 час).
  • Дополнительный ключ. Сюда сохраняется результат запроса, но ttl устанавливается больше, чем у основного ключа. Больше на время выполнения запроса плюс небольшой запас (в примере: 1 час кэша + 10 секунд запроса + 5 секунд запаса).

В момент, когда в кэше удаляются данные, необходимо сначала записать в основной ключ значение из запасного, а только потом приступить к выполнению SQL запроса.


memcache_connect('localhost', 11211);

if ( !$list = memcache_get(‘user_ages’) )

{

**memcache_set(‘user_ages’, memcache_get(‘user_ages_backup’), 60*60);**

$sql = ‘SELET count(*), age FROM users GROUP BY age’;

$q = mysql_query($sql);

while ($row = mysql_fetch_assoc($q)) $list[] = $row;

memcache_set(‘user_ages’, $list, 60*60);

**memcache_set(‘user_ages_backup’, $list, 60*60 + 10 + 5);**

}

## Сначала записываем данные из запасного ключа в основной

Таким образом, более одного запроса параллельно выполнено не будет.

Другие решения

Также можно использовать cron задачи для обновления данных в кэше. Тогда посетители никогда не смогут вызвать тяжелые запросы. Но в этом случае лучше использовать постоянные хранилища для кэширования (например Redis), т.к. Memcache не гарантирует сохранности данных.

Самое важное

Эту методику лучше применять для избавления от возможных критических ситуаций. Но крайне желательно избавляться от подобных запросов, оптимизируя сами запросы. Помимо SQL запросов, этот же подход можно применять и для внешних API запросов.

Останні статті

Обучение Power BI – какие онлайн курсы аналитики выбрать

Сегодня мы поговорим о том, как выбрать лучшие курсы Power BI в Украине, особенно для…

13.01.2024

Work.ua назвал самые конкурентные вакансии в IТ за 2023 год

В 2023 году во всех крупнейших регионах конкуренция за вакансию выросла на 5–12%. Не исключением…

08.12.2023

Украинская IT-рекрутерка создала бесплатный трекер поиска работы

Unicorn Hunter/Talent Manager Лина Калиш создала бесплатный трекер поиска работы в Notion, систематизирующий все этапы…

07.12.2023

Mate academy отправит работников в 10-дневный оплачиваемый отпуск

Edtech-стартап Mate academy принял решение отправить своих работников в десятидневный отпуск – с 25 декабря…

07.12.2023

Переписки, фото, история браузера: киевский программист зарабатывал на шпионаже

Служба безопасности Украины задержала в Киеве 46-летнего программиста, который за деньги устанавливал шпионские программы и…

07.12.2023

Как вырасти до сеньйора? Девелопер создал популярную подборку на Github

IT-специалист Джордан Катлер создал и выложил на Github подборку разнообразных ресурсов, которые помогут достичь уровня…

07.12.2023