Стандартная связка кеширования для сайтов - php+memcached. Обычно, на форумах рекомендуют использовать примерно такое:
1. Вызывается страница
2. Смотрим, есть ли кеш для нее (создан или истекло время хранения)
3. Если есть, отдаем кешированый контент
4. Если нет, то создаем кеш и отдаем его содержимое.
Такой алгоритм замечательно работает в случае, если у вас время захода отдельных юзеров на сайт не превышает времени генерации отдельной страницы кеша. Простыми словами, если у вас два с половиной юзера в час, то такая схема замечательно работает. Но при этом смыла в таком кешировании нет никакого.
Данный алгоритм, однозначно не работает в случае слешдот эффекта. Хотя, казалось бы, как раз от него мы и пытаемся защититься при помощи нашей системы кеширования.
С алгоритмом выше, при массовом наплыве траффика происходит примерно следующее:
1. Приходит первый юзер с запросом на нашу страницу. В кеше ее нет, поэтому запускается “тяжелая” отработка страницы, с дерганием сложных квери к базе данных и тп.
2. В следующий момент, пока первый запрос еще не отработан. Для второго юзера ситуация аналогична. Начинает снова генерится страница, поскольку данных в кеше еще нет.
3. И так далее. В итоге, все свободные процессы начинают обрабатывать один и тот же запрос, чтобы создать кешированную страницу. Поскольку процесс создания достаточно “тяжел”, сервак утыкается либо в ограничения http-сервера, либо в БД, либо в количество инклюдов итп. Смотря где у нас есть “бутылочные горлышки” (bottleneck)
Выхода из ситуации есть два. Первый (идеальный) - контент для кеша генерится априори на бекэнде, без участия юзеров в принципе. Но это не всегда возможно сделать.
Второй - почти что хак, так сказать перанальный вариант. Тем не менее, простой, как и все гениальное
Состоит он в том, что при первом запросе к странице, первая операция - создание пустой записи в кеше, с увеличенным временем expire. Минус: Пока отрабатывает один (и только один) процесс на создание страницы, остальные юзеры видят пустую страницу (кеш то не создан еще). Обходится просто - (см. первый вариант выше: контент для кеша генерится на бекенде превентивно)
Плюсы все что называется налицо. Слешдот эффект переходит уже в канальную область и возможности железа и операционке по обработке http. БД дергается только один раз для одной страницы.
В общем случае, все решается примерно так:
$memcache = new Memcache;
$memcache->pconnect('localhost', 11211);$md5 = md5(rtrim($_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'],’/'));
if ($get_result = $memcache->get($md5)) {
//if (time()<($get_result->int_attr - rand(0,60))) {
if (time()<$get_result->int_attr) {
print $get_result->str_attr;
$memcache->close();
exit;
} else {
$get_result->int_attr += 60+rand(5,20);// добавляем ему 30 секунд, чтобы залочить следующие треды
$memcache->set($md5, $get_result, false, 3600);// 1 hour total cache
}
}… здесь идет собственно создание контента …
$tmp_object = new stdClass;
$tmp_object->str_attr = $t->subst(’OUT’);
if ($_SERVER['REQUEST_URI']==’/') {
//если корневые страницы, то 1 минута кеш
$delta = 60;
} else {
//если внутренние - то 3 мин
$delta = 180;
}
$tmp_object->int_attr = time() + $delta;// delta минут, хуле
$memcache->set($md5, $tmp_object, false, 3600);// 1 hour total cache


Ответило: 3
Будь всегда в теме, подпишись на RSS ленту комментов.
В тему