Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > PHP: Для профи > Кэширование в CMS


Автор: kanaris 30.8.2008, 16:05
Хочу услышать советы тех, кто делал кеширование в своих движках или сталкивался с подобными проблемами ну и вообще всех кто знаетsmile
Придумываю алгоритм кеширования веб-страниц в движке. Обычно это делается в след. этапы:

1) из БД извлекается инфа о последнем обновлении страницы (по заданному урлу, кукам, и др)
2) извлекается последний образ кеширования страницы (по заданному урлу, кукам, и др)
3) если последний образ страницы устарел, сгенерить страницу по новой и обновить последний образ в базе.
4) если образ не устарел, в браузер выдать эту готовую страницу и пропустить процесс генерирования страницы (инклуд модулей, обработка данных, парсинг, етс).

Возникает вопрос: как узнать, изменилась ли страница, не генерируя ее заново? На обновление страницы влияют такие факторы (не полный список):
1) изменение конкретной таблицы в БД
2) изменение файлов на сервере (если скрипт считывает какую-то директорию)
3) фактор времени (например, текущее число на календаре) - страница уже будет другой следующего числа
4) Залогиненный юзер (для каждого юзера одна и та же страница будет другой, например панель "Здравствуйте Пользователь! У вас 20 новых сообщений")
5) скин
6) язык
7) ...

Также нужно предусмотреть такую проблему: если изменилась одна таблица (добавили/удалили/отредактировали запись), то должна измениться только та страница, на которую повлияла эта запись, а не все страницы, использующие эту таблицу (которые бы не изменились при редактировании таблицы), и чтобы страница не перегенеривалась, если она не изменилась.
В общем нужно придумать самый гибкий и универсальный вариант. кто что посоветует...

Автор: Daevaorn 30.8.2008, 16:23
В ORM и других компонентах предусмотреть систему сигналов, на которые можно повесить обработчики. Через них осуществлять инвалидацию кеша.
Ну и вообще, кешировать всю страницу почти всегда не оправдано и глупо, лучше и гибе кешировать куски html и промежуточные данные.

Автор: Mal Hack 30.8.2008, 23:26
http://forum.vingrad.ru/index.php?showtopic=222972&view=findpost&p=1602378

Цитата
skyboy, ну тут смысл вообще какой. Начиналось все с того, что я долго думал, как снизить нагрузку на сервер практически до нуля (до уровня обработки статических страниц). Динамика помимо того что генерирует страницу сохраняет ее копию в качестве статической html. При обращении к движку он делает проверку, мол а надо ли страницу генерировать? (ответ на "надо ли" может зависеть от многих факторов, не суть в этом), если надо - генерируем, если нет, тупо через readfile отдаем пользователю уже готовый html. Процесс - псевдо-кэширование.

Додумался я в свое время до частичной генерации, например для форумов. Сейчас уже, конечно и не вспомню (сразу) всех нюансов.

Вот и в твоей ситуации можно также поступить, генерировать html, скидывать их (вместе с картинками и прочей добавляющейся информацией) на второй сервер. Соответственно. если основной отрубится у юзера остается статическая версия сайта, которая спокойно может использоваться.

P.S. я надеюсь ты продумал ситуацию, когда у тебя первый сервак отказал, второй работает, обновляет СВОЮ базу, а потом, когда заработает первый ты должен уже его синхронизировать со вторым...

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


Тема в догонку: http://forum.vingrad.ru/forum/topic-82069.html

Автор: lukas 31.8.2008, 00:08
Самое простое что я писал для кеширования...

Кеширует html кусками, а также переменные...

Код

<?
/*
 Cache Library 1.0
 Библиотека для кеширования данных,
 а также SQL запросов
*/
define('DEF_CACHE_DIR',DOC_ROOT.'/cache/');

class CCache{
    public $time = 3600;
    public $cache_id;
    public $dir = DEF_CACHE_DIR;
    public $ext = '.cache';
    public $start_cache = false;
    public $cached = false;
    
    function __construct($time=null,$cache_id=null,$dir=null){
    if (isset($time))     $this->time     = $time;
    if (isset($cache_id)) $this->cache_id = $cache_id;
    if (isset($dir))      $this->dir      = $dir;
    }
    
    function is_cached(){
    if (file_exists($this->dir . $this->cache_id . $this->ext)){
        return time() <= (filemtime($this->dir . $this->cache_id . $this->ext)+$this->time);
        } else return false;
    }
    
    function read_cache_file(){
    return file_get_contents($this->dir . $this->cache_id . $this->ext);
    }
    
    function write_cache_file($str){
    return file_put_contents($this->dir . $this->cache_id . $this->ext,$str);
    }
    
    function start_cache(){
    $this->cached = $this->is_cached();
    ob_start();
    }
    
    function end_cache(){
    if (!$this->cached){
        $str = ob_get_contents();
        $this->write_cache_file($str);
    } else $str = $this->read_cache_file();
    ob_end_clean();
    echo $str;
    }
    
    function var_cache($var){
    $str = serialize($var);
    return $this->write_cache_file($str);
    }
    
    function read_var(){
    return unserialize($this->read_cache_file());
    }
    
    function load_var(&$var){
    $var = $this->read_var();
    }
    
}

if (empty($GLOBALS['obCache'])) $GLOBALS['obCache'] = new CCache;
$obCache = &$GLOBALS['obCache'];

function write_var_cache($var,$time,$cache_id){
    global $obCache;
    $obCache->time = $time;
    $obCache->cache_id = $cache_id;
    if (!$obCache->is_cached()) return false;
    else return $obCache->var_cache($var);
}

function is_var_cache($time,$cache_id){
    $obCache->time = $time;
    $obCache->cache_id = $cache_id;
    return $obCache->is_cached();
}

function read_var_cache($time,$cache_id){
    global $obCache;
    $obCache->time = $time;
    $obCache->cache_id = $cache_id;
    return $obCache->read_cache_file();
}

function html_cache($time,$cache_id){
    global $obCache;
    $obCache->time = $time;
    $obCache->cache_id = $cache_id;
    $obCache->start_cache();
}

function end_html_cache(){
    global $obCache;
    $obCache->end_cache();
}

?>

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)