Для борьбы с нагрузкой простым и эффективным средством является файловое кеширование.
Для его реализации делаем следующее...
в папке /engine/cache/ создаем папку fcache и ставим на нее права 777
Открываем файл index.php
Находим:
define ( 'DATALIFEENGINE', true );
вставляем выше:
////////////////////////////////////Файловое кеширование///////////////////////////////////// if( $_SESSION['dle_user_id'] == false && $_SERVER['REQUEST_METHOD'] == "GET" ) { $fcache = $_SERVER['DOCUMENT_ROOT'] . '/engine/cache/fcache/' . md5( $_SERVER['REQUEST_URI'] ) . '.html'; if ( file_exists( $fcache ) && filemtime( $fcache ) > time() - 3600*3 ) exit( file_get_contents( $fcache ) ); } /////////////////////////////////////////////////////////////////////////////////////////////
Находим:
GzipOut();
Вставляем выше:
///////////////////////////////Файловое кеширование////////////////////////////// if( $_SESSION['dle_user_id'] == false && $_SERVER['REQUEST_METHOD'] == "GET" ) file_put_contents( $fcache, ob_get_contents() ); /////////////////////////////////////////////////////////////////////////////////
Все. Теперь у вас в папке /engine/cache/fcache/ будет накапливаться кеш при каждом посещени сайта незарегестрированным юзером, (гостем).
3600*3 - означает что время жизни кеша 3 часа. По истечении которого кеш будет перезаписан.
Но, для того чтобы кеш редкооткрываемых страниц не копился и не забивал вам диск, создаем следующий скрипт в корне сайта и ставим в кроне на выполнение его каждые 15 минут например.
Например файл clear.php
<?php $cache_time = 3600*3+60; // время жизни кеша + 60 секунд. $dir = "/var/www/username/data/www/site.ru/engine/cache/fcache/"; // абсолютный путь до папки с кешем echo "site.ru: "; // домен вашего сайта //==========================Очистка устаревшего файлового кэша============// $del = 0; $fdir = opendir( $dir ); while( ( $file = readdir( $fdir ) ) !== false ) { $filetype = explode( '.', $file ); $type = array_pop( $filetype ); $fcache = $dir . $file; if ( $type == 'html' AND file_exists( $fcache ) AND filemtime( $fcache ) < time() - $cache_time ) { $del++; unlink( $fcache ); } } closedir( $fdir ); echo $del . " files deleted \n\r"; //========================================================================// ?>
Все. Теперь вы можете забыть о нагрузке на базу данных!!!
А теперь товарищи самое интересное и вкусное )))
Новый вариант кеширования с использованием memcached.
Про то как устанавливать memcached на сервере и библиотеку для его работы с php я писать не буду. Вам достаточно обратиться к вашему хостинг провайдеру и вам его установят. А тот кто сам администрирует свои сервера тот и сам знает как его ставить Там все делается за пару секунд...
Я расскажу непосредственно о том как этот самый memcached использовать с пользой для вашего сервера, приминительно непосредственно к движку DLE (любой версии).
Единственное скажу что необходимо выделить оперативки для memcached примерно 3 четверти от того сколько занимало у вас файловое кеширование. То есть если файловый кеш скажем со сроком жизни 3 часа занимал у вас 200 мегабайт, то для memcached выделите 150 мегабайт памяти.
Итак начнем...
1. Открываем index.php, находим:
define ( 'DATALIFEENGINE', true );
Вставляем выше:
////////////////////////////////Кеширование в Memcached /////////////////////////////////////////// if( $_SESSION['dle_user_id'] == false && $_SERVER['REQUEST_METHOD'] == "GET" ) { $memcache = memcache_connect( 'localhost', 11211 ); $memkey = md5( $_SERVER['SERVER_NAME'] . $_SERVER['REQUEST_URI'] ); $mempage = memcache_get( $memcache, $memkey ); if( $mempage ) exit( $mempage ); } ///////////////////////////////////////////////////////////////////////////////////////////////////
Находим:
GzipOut ();
Вставляем выше:
////////////////////////////////Кеширование в Memcached /////////////////////////////////////////// if( $_SESSION['dle_user_id'] == false && $_SERVER['REQUEST_METHOD'] == "GET" ) { memcache_set( $memcache, $memkey, ob_get_contents(), MEMCACHE_COMPRESSED, 3600*2 ); memcache_close( $memcache ); } ///////////////////////////////////////////////////////////////////////////////////////////////////
3600*2 это время жизни кеша, 3600 секунды это 1 час, умножаем 3600 на 2 получается время жизни 2 часа.
2. Всё! Наслаждаемся процессом.
Немного о плюсах и минусах данного способа кеширования. Ну во первых, кеширование похоже на файловое, показанное мною несколькими постами выше.
Плюсы.
1. Еще более быстрый ответ сервера, так как все данные кеша хранятся в оперативной памяти.
2. Никакой нагрузки на HDD. (Меньше износ, больше проживет)
3. Кеш занимает меньше места, так как он сжимается средствами memcached.
4. Как вы могли заметить, я не привел ничего для удаления устаревшего кеша. А все потому что как только время его жизни устаревает в памяти, память занимаемая старым кешем высвобождается сама.
Минусы.
1. Необходимо чтобы у вас было нужное количество оперативки.
2. Если на сервере несколько сайтов, и все они используют данный вид кеширования, то при очистке кеша, удаляется кеш для всех сайтов. То есть невозможно удалить весь кеш только для одного конкретного сайта. С оперативкой такие фокусы не проходят. Либо все либо ничего... Но меня этот факт не сильно напрягает.
3. Больше минусов не вижу
Да кстати, для того чтобы очистить весь кеш в памяти, необходимо запустить такой вот скрипт:
<?php $memcache = memcache_connect( 'localhost', 11211 ); memcache_flush( $memcache ); memcache_close( $memcache ); ?>
После выполнения этого скрипта, ОЗУ не очищается моментально, но весь кеш в памяти помечается как устаревший, а система потом сама высвобождает память по мере необходимости.
Немного статистики...
Если файловое кеширование у меня занимало примерно 300 мегабайт на HDD, то memcached кеширование занимает всего 150 мегабайт памяти.
Если не использовать кеширование вообще, то есть использовать только родное DLE'шное, то MySQL жрал у меня 50% CPU на сервере при посещаемости 100 тыс уников в сутки. А с использованием кеширования будь то файловое или memcached, MySQL жрет не более 10% CPU. Сказка не правда ли? При всем при этом я использую время жизни кеша всего 2 часа.
Как проверить, что memcache работает правильно?
Обычно Memcached стоит на localhost и доступен через порт 11211
Смотрим статистику
<?php $memcache = new Memcache; $memcache->connect('localhost',11211); print_r($memcache->getStats()); ?>
Чтобы кеш можно было чистить вместе с остальным кешем нажатием кнопки в админке .
Для этого нужно открыть /engine/inc/main.php найти там: clear_cache(); и перед этим добавить:
///// ЧИСТИМ ФАЙЛОВЫЙ КЭШ ///// $fcachedirname = ENGINE_DIR.'/cache/fcache'; if ($objs = glob($fcachedirname."/*")) { foreach($objs as $obj) { is_dir($obj) ? removeDirRec($obj) : unlink($obj); } } rmdir($fcachedirname); @mkdir (ENGINE_DIR.'/cache/fcache', 0777); @chmod (ENGINE_DIR.'/cache/fcache/', 0777); ////////////////
кстати, на старой версии ДЛЕ сделал вот так проверку на залогиненого. месяц работы - полет нормальный 🙂
////////////////////////////////////Файловое кеширование///////////////////////////////////// if( $is_logged == false && $_SERVER['REQUEST_METHOD'] == "GET" ) { $fcache = $_SERVER['DOCUMENT_ROOT'] . '/engine/cache/fcache/' . md5( $_SERVER['REQUEST_URI'] ) . '.html'; if ( file_exists( $fcache ) && filemtime( $fcache ) > time() - 3600*1 ) exit( file_get_contents( $fcache ) ); } /////////////////////////////////////////////////////////////////////////////////////////////
и в футере
///////////////////////////////Файловое кеширование////////////////////////////// if( $is_logged == false && $_SERVER['REQUEST_METHOD'] == "GET" ) { file_put_contents( $fcache, ob_get_contents() ); } /////////////////////////////////////////////////////////////////////////////////
и в конце вот такая модификация для улучшения индексирования сайта:
////////////////////////////////////Файловое кеширование///////////////////////////////////// if( $is_logged == false && $_SERVER['REQUEST_METHOD'] == "GET" ) { $fcache = $_SERVER['DOCUMENT_ROOT'] . '/engine/cache/fcache/' . md5( $_SERVER['REQUEST_URI'] ) . '.html'; if ( file_exists( $fcache ) && filemtime( $fcache ) > time() - 3600*1 ) { $slastModified = gmdate('D, d M Y H:i:s', filemtime($fcache)) . ' GMT'; $etag = md5_file($fcache); $headers = getallheaders(); if (isset($headers['If-Modified-Since'])) { $modifiedSince = explode(';', $headers['If-Modified-Since']); $modifiedSince = strtotime($modifiedSince[0]); if ($lastModified <= $modifiedSince) { header('HTTP/1.1 304 Not Modified'); header('Last-Modified: ' . $slastModified ); exit(); } } header('Last-Modified: ' . $slastModified ); header("Etag: $etag"); exit( file_get_contents( $fcache ) ); } } /////////////////////////////////////////////////////////////////////////////////////////////
больше инфы по ссылкам
Заголовки Last-Modified и If-Modified-Since
How to get 304 Not Modified Header from CDN