Skip to content


Проблема дедлоков (deadlock) при использовании кеширования memcached в php

Стандартная связка кеширования для сайтов - 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

google.com bobrdobr.ru del.icio.us technorati.com linkstore.ru news2.ru rumarkz.ru memori.ru moemesto.ru

В рубрике High Load, PHP, Обо всем. Тэги .

Меня читают

  • Секс в "Артеке" (ФОТО)
  • Как стать сверх человеком
  • кубізм і мода
  • site:rabotain.com
  • Andrey Lenitsky
  • Ответило: 3

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

    В тему

    1. Nginx Apache не для всех доменов | Вебпрограмминг в действии добавлено к этому посту _ 08.01.2009

      [...] идея обратного проксирования в том, что Nginx вешается на 80й порт и принимает на себя [...]

    2. Kohana 2.3 routes. Хак для мультиязычного сайта | Вебпрограмминг в действии добавлено к этому посту _ 08.01.2009

      [...] условия добавлено, чтобы разные урлы парсились [...]

    3. Процесс: плагин для внутристраничной линковки на базе латентно-семантического анализа (LSA) | Вебпрограмминг в действии добавлено к этому посту _ 08.01.2009

      [...] “детского писателя Пупкинса”, то с точки зрения LSA, вторая ссылка гораздо надежнее, ибо тематика сайтов [...]

    Можно чутка HTML

    (обязателен)

    (обязателен, показан не будет)

    или, ответьте через трекбек.