DLE: полное кэширование страниц

Для борьбы с нагрузкой простым и эффективным средством является файловое кеширование.
Для его реализации делаем следующее…
в папке /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 я писать не буду. Вам достаточно обратиться к вашему хостинг провайдеру и вам его установят. А тот кто сам администрирует свои сервера тот и сам знает как его ставить DLE: полное кэширование страниц Там все делается за пару секунд…
Я расскажу непосредственно о том как этот самый memcached использовать с пользой для вашего сервера, приминительно непосредственно к движку DLE (любой версии).

ПОЛЕЗНО  PageSpeed Insights: Используйте кеш браузера

Единственное скажу что необходимо выделить оперативки для 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 );
?>

После выполнения этого скрипта, ОЗУ не очищается моментально, но весь кеш в памяти помечается как устаревший, а система потом сама высвобождает память по мере необходимости.

ПОЛЕЗНО  Тюнинг сервера Apache

Немного статистики…
Если файловое кеширование у меня занимало примерно 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

  • Здравствуйте! Устанавливал ваши коды — все работает на DLE 10.1 но после обновления движка до 10.5 все перестало работать! Не пишет кеш в папку fcache и все, проверял права и тд — не работает.

    • Roman NMSK

      привет, а при обновлении на затерся код в index.php? и я бы еще проверил — что отдается в параметре $is_logged — возможно его изменили или переименовали?

  • Yaroslav

    Модификация для улучшения индексирования не работает на связке nginx+php-fmp

  • Алексей Стаханов

    Подскажите, как бы все это поставить на dle 10.6? Дело в том что не могу найти, где находится GzipOut (); , в index.php его нет, вроде как еще с 10.5 его перенесли, может и раньше.

    • Алексей Стаханов

      В общем установил. Но есть маленькая проблема, после смены страницы, постоянно выходит с аккаунта, как можно решить данную проблему?