[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Использование файлового кэша
Игорь_Vasinsky
Вообщем обламал меня хостер с memcache, пришлось вернуться к файловому кэшу в ручную.
Сначала подумал - надо "похабрить"... и сразу же перебил себя мыслью, что механизм не такой уж и сложный.

Принцип кеширования прост:

Примечание: т.к. я писал алгоритм для постоянно обновляемого ресурса - то предусмотрел такое понятие как "Время жизни кэша"

- Если не найден файл кэша страницы (причём расматривается не просто файл, а файл + REQUEST_URI), то выводим контент и пишем файл кэша
- Если файл кэша найден и он "не старше" установленного срока - вывести страницу из кэша, не обращаясь к БД
- Если файл кеша существует, но он старше установленного срока - перезапишем файл кэша.

Интеграция - тоже очень проста.

1. файл headcache.php - инклудим самым первым, либо в файл точки входа (если предусмотрена одна точка входа, например index.php), либо как это было модно и модно и сейчас в файл "чердака" - header.php. В обоих случаях - файл должен быть подключён до любого вывода.

2. файл footcache.php - инклудим самым последним, либо в файл точки входа (если предусмотрена одна точка входа, например index.php), либо
в файл "подвала" - footer.php. В обоих случаях - файл должен быть подключён в конце, после любого вывода.

Листинг headcache.php
<?php
header("Content-type: text/html; charset=utf-8");

//урежем session_id - если вдруг она проскочит в url
if(substr_count('?', $_SERVER['REQUEST_URI']) > 0)
$uri = explode('&session_id', $_SERVER['REQUEST_URI']);
else
$uri = explode('?session_id', $_SERVER['REQUEST_URI']);

$fileName = md5($uri[0]);

//Установим часовой пояс
date_default_timezone_set( 'Europe/Moscow' );

//Множитель - 1 час в секундах
$factor = 3600;
//Врема жизни кэша (1 час)
$timeLifeCache = 1*$factor;
//Папка для кэша
$cache = $_SERVER['DOCUMENT_ROOT'].'/cache/';

ob_start();
?>


//Show all content this page
//Весь выводимый контент сайта со всеми проинклуженными файлами


Листинг footcache.php
<?php
$contentPage = ob_get_contents();
ob_end_clean();

//Если файла кэша не существует - создадим его, контент выведем из буфера
if(!file_exists('cache/'.$fileName))
{
echo 'Из буфера....<br />';

echo $contentPage;
//Записать в буфер
file_put_contents($cache.$fileName, $contentPage, LOCK_EX);
}
//Если файл кеша найден и не старше установленного времени - выведем из кэша
elseif(file_exists($cache.$fileName) AND (time() - filemtime($cache.$fileName)) <= $timeLifeCache)
{
$cachePage = file_get_contents($cache.$fileName);

echo 'Из кэша...<br />';

echo $cachePage;
}
//Если файл кеша найден и старше установленного времени - перезапишем кэш, контент выведем из буфера
elseif(file_exists($cache.$fileName) AND (time() - filemtime($cache.$fileName)) >= $timeLifeCache)
{
file_put_contents($cache.$fileName, $contentPage, LOCK_EX);

echo 'Из буфера.... и записали новый кэш<br />';

echo $contentPage;
//Записать в буфер
file_put_contents('cache/'.$fileName, $contentPage);
}
?>


т.е. весь контент, при отсутствии кэша - мы буферизируем.


Как такой ход для объёмного проекта????
какие недостатки?
какие подводные камни (кроме того что нужно контролировать дисковое пространство)?



Спустя 7 минут, 45 секунд (3.05.2012 - 13:22) Nikitian написал(а):
Если заходит посетитель без кук, либо в первый раз, то в ссылки прописывается идентификатор сессии - это будет уникализировать каждый раз request_uri, т.е. на такие посещения кэширование работать не будет и будет генерить туеву кучу ненужных файлов.

Спустя 10 минут, 20 секунд (3.05.2012 - 13:32) Игорь_Vasinsky написал(а):
не будет - если парсить URI и урезать session_id

$url = explode('&session_id', $_SERVER['REQUEST_URI']);


использовать $url[0]

так же можно обойти эту шляпу?

Спустя 2 минуты, 9 секунд (3.05.2012 - 13:34) Nikitian написал(а):
Цитата (Игорь_Vasinsky @ 3.05.2012 - 13:32)
не будет - если парсить URI и урезать session_id

<pre class="sh_sourceCode" rel="php"><span class="sh_variable">$url</span> <span class="sh_symbol">=</span> <span class="sh_function">explod</span><span class="sh_symbol">(</span><span class="sh_string">'&session_id'</span><span class="sh_symbol">,</span> <span class="sh_variable">$_SERVER</span><span class="sh_symbol">[</span><span class="sh_string">'REQUEST_URI'</span><span class="sh_symbol">]);</span></pre>

использовать $url[0]

так же можно обойти эту шляпу?

Можно, но в коде этого нет.
Опять же тут опечатка в названии функции и не учтена возможность наличия параметров после этой строки. Лучше сделать примерно так.


$url=parse_url($url)['path'].'?'.http_build_query(unset(parse_str(parse_url($url)['query'] )[session_name()]))

Это псевдокод, чтобы понятна была идея. Жаль, что нельзя так писать :)

Спустя 2 минуты, 6 секунд (3.05.2012 - 13:37) Игорь_Vasinsky написал(а):
laugh.gif а это как раз то - для чего этот топик

Цитата
какие подводные камни (кроме того что нужно контролировать дисковое пространство)?
wink.gif

спс

Спустя 3 минуты, 52 секунды (3.05.2012 - 13:40) Игорь_Vasinsky написал(а):
ну вот добавил такой кусок в начало

if(substr_count('?', $_SERVER['REQUEST_URI']) > 0)
$uri = explode('&session_id', $_SERVER['REQUEST_URI']);
else
$uri = explode('?session_id', $_SERVER['REQUEST_URI']);


не промахнулся?

расматривал как единственный $_GET, так и несколько

Спустя 5 минут, 43 секунды (3.05.2012 - 13:46) inpost написал(а):
Игорь_Vasinsky
Обновляемый кеш я в своём проекте повесил на крон, чтобы каждый раз не дёргать файл и не проверять его время.
Файловый кеш быстрее мем-кеша.

А действительно есть проблема? Я бы на твоём месте сейчас кешировал бы только проблемные места, тогда множества ненужных файлов не было бы.

Спустя 4 минуты, 23 секунды (3.05.2012 - 13:51) Игорь_Vasinsky написал(а):
проблемы нет, но есть вероятность - когда она появиться - не будет времени biggrin.gif

по этому лучше предусмотреть сейчас.

постарался написать такой алгоритм, чтоб при внедрении нужно было делать минимум телодвижений.

а ведь почти начал переписывать на memcache... там подолше и по говнокодистей бы вышло.


Т.е. твой вариант - не предусматривает кеширование пользовательского поиска

и потом - я хочу минимум на 3-4 часа кешировать, что позволит снизить нагрузку в
5-6 раз в сутки.

Спустя 3 минуты, 14 секунд (3.05.2012 - 13:54) inpost написал(а):
Игорь_Vasinsky
Поиск же всегда выдаёт одно и то же. При этом результат поиска будет меняться на уровне изменения данных из админки, как я понимаю, поэтому я бы расширил функционал формирования кеша как раз из админки. То есть ты добавил/удалил какую-то запись, переделал кеш.
Или как это делается на движках. Отключается формирование кеша, (он работает по старым записям), далее пакетом загружаются данные - 10 товаров, далее кеш включается с автоматическим пересчётом.
Вот я к такому способу кеширования более склонен.

Спустя 2 минуты, 24 секунды (3.05.2012 - 13:56) Игорь_Vasinsky написал(а):
т..к. контент постоянно обновляется - то и пользовательский поиск расширяется

да. нужно предусмотреть вариант если запрашиваемы контент отсутствует - то не зачем писать кэш (+ удалить существующий).

как то заголовками чтоль маячить... нужно подумать, т.к. я тупо 404 не выкидываю...

Спустя 17 минут, 19 секунд (3.05.2012 - 14:13) Oyeme написал(а):
Кэш будет использоваться непосредственно только для прямых запросов.

0.Вам не следует использовать отношения с таблицами. It doesn't make sense.
1.Вы можете обновлять сразу кэш,если что-то поменялось.
2.Как тут сказали крон,это хороший способ фильтрации.
3.Вам следует ставит кэш на те места которые этого требуют,то есть грамотно распределить кеширование.

Спустя 8 минут, 33 секунды (3.05.2012 - 14:22) Игорь_Vasinsky написал(а):
средний вес 1 страницы = 70кб
на данный момент их около 15500 шт

та что при 20 000 страниц - всего около 1,5 Гб кэша. (нужно пересмотреть малость алгоритм... стока мусора нам не к чему...)


Расход памяти

localhost
2926.1796875 kb
3145.234375 kb

Virtual Hosting
7497.9921875 kb
7733.203125 kb

На данный момент на каждой странице у меня от 3 до 4 запросов по выборке.

скоро добавится ещё 2 на UPDATE () + 2 SELECT


памяти жрёт больше, но я надеюсь это компенсируется т.к. не дёргается БД?

Спустя 18 минут, 59 секунд (3.05.2012 - 14:41) Игорь_Vasinsky написал(а):
Gzip - тока для html страниц ?????? чёт везде так акцент делают..

И как бы мне файлы кеша "сжимать", не в буквальном смысле, а удалять табы, переносы строк

есть у кого нить функция такая?

минимум что в голову пришло это

$contentPage = strtr(ob_get_contents(), array('    '=>'', "\r"=>'', "\n"=>'', '  '=>''));

Спустя 7 минут, 31 секунда (3.05.2012 - 14:49) Nikitian написал(а):
Цитата (Игорь_Vasinsky @ 3.05.2012 - 14:41)
И как бы мне файлы кеша "сжимать", не в буквальном смысле, а удалять табы, переносы строк

есть у кого нить функция такая?

минимум что в голову пришло это

$contentPage = strtr(ob_get_contents(), array('    '=>'', "\r"=>'', "\n"=>'', '  '=>''));

Спустя 12 минут, 51 секунда (3.05.2012 - 15:01) Игорь_Vasinsky написал(а):
чёт я не въезжаю как юту внедрить laugh.gif

проинклудить все 3 файла и вместо ob_start() вписать ob_start(array('Optimize', 'html')); ?????

Спустя 3 минуты, 49 секунд (3.05.2012 - 15:05) Oyeme написал(а):
Для чего Вы кешируете всю страницу ,а не сами данные с запроса? wink.gif

У Вас нет memache,сделайте так же только на файлах.

Спустя 4 минуты, 52 секунды (3.05.2012 - 15:10) Игорь_Vasinsky написал(а):
не не. я решил именно всю страницу.

основное требование "меньше телодвижений"

Спустя 19 минут, 29 секунд (3.05.2012 - 15:30) Oyeme написал(а):
Получаться как раз наоборот,один запрос поменял значение и Вы заново генерируете кэш со всех запросов. wink.gif И так каждый раз.
Вы же храните всю страницу целиком.

Страница(Включает в себя 21 запрос)
1 - Ok
2 - ОК
...
21 - chanaged

Генерируем заново файл ,и заново выполняем 21 запрос.

И всё это из-за,одного запроса.

Спустя 3 минуты, 39 секунд (3.05.2012 - 15:33) SitnikovArtur написал(а):
Я против md5 в механизме.

При изменении меню или дизайна кеш нужно чистить и создавать потом новый. Если страничек 1000, а меню поменялось только на 20-ти из них, то достаточно сбросить только 20 страничек, удалив конкретную директорию, а с md5 это целая головная боль.
И зачем вообще время жизни кеша? Не проще снабдить обработчики редактирования инфы чисткой изменений в кеше, чтобы однажды созданный файл, не подвергающийся в дальнейшем изменениям, был сгенерирован 1 раз за всю историю жизни проекта?

Плюс ко всему на диске будет лежать папка, отображающая структуру сайта, которую легко можно перенести даже на хостинг без php. То есть с помощью такого кеширования можно будет делать полностью статические сайты.

Спустя 2 минуты, 59 секунд (3.05.2012 - 15:36) vital написал(а):
Цитата
Файловый кеш быстрее мем-кеша.

Это вот кто это вот такое сказал? Можно цифры?
Т.е. прокрутитить пластину диска, переместить головку, считать данные, быстрее чем взять данные прямо из оперативы по прямому адресу?
Не шутите так.

Варианты возможны мб при SSD диске, и то не факт.

Спустя 3 минуты, 42 секунды (3.05.2012 - 15:40) Игорь_Vasinsky написал(а):
так. возник вопрос. а обфуксацией кешируемого кода - можно размер данных (вес) в файле кеша сократить?

Спустя 9 минут, 24 секунды (3.05.2012 - 15:49) inpost написал(а):
vital
Мем-кеша на ПХП. Возможно на других языках, на который и используется метод мем-кеша, он будет в итоге быстрее. Существует более оптимальные способы использования кеша в меме, достаточно посмотреть на сайты, которые написаны на ПХП и считаются самыми популярными.

На обычном, не ССД винте.
А ты пробовал? Запусти и проверь сам. Поместил данные, достал данные. Всё очень просто, проверяй.

Спустя 1 минута, 13 секунд (3.05.2012 - 15:50) Игорь_Vasinsky написал(а):
Цитата
Если страничек 1000, а меню поменялось только на 20-ти

так. это решение для конкретного проекта - для моего.

md5 - я придаю божеский вид имени файлов - вместо 255 длины URL

время жизни - для того чтоб контент рано или поздно - но обнавлялся laugh.gif


так я и не понял как пользоваться тем оптимизатором.


эй.. а ну не холиварить!

Спустя 1 минута, 7 секунд (3.05.2012 - 15:52) Игорь_Vasinsky написал(а):
как грузиться??? http://hdkinozavr.ru/

Спустя 2 минуты, 32 секунды (3.05.2012 - 15:54) Oyeme написал(а):
144 requests
3.2 MB
19.33s (onload: 25.79s)
laugh.gif

Вы только что потеряли посетителя.

Спустя 2 минуты, 33 секунды (3.05.2012 - 15:57) Игорь_Vasinsky написал(а):
переходите на VPN... так вы сломаете свой USB - модем.

Спустя 7 дней, 21 час, 38 минут, 30 секунд (11.05.2012 - 13:35) Игорь_Vasinsky написал(а):
хостер забил на поддержку, поэтому крон я не могу завести (или они сами не могут его завести :D )

вообщем вернусь к теме, использование данной схемы - показало себя с хорошей стороны (т.к. какой то период нет запросов в БД, а тупо хватается статичный документ), исключая момента, что я планировал подчищать кэш такой схемой каждый час с помощью крона

   //Множитель - 1 час в секундах
$factor = 36;
//Врема жизни кэша (1 час)
$timeLifeCache = 2*$factor;

$files = glob('cache/*');

foreach($files as $file)
{
if(time() - filemtime($file) >= $timeLifeCache)
{
if(unlink($file))
echo 'DELETED: '.$file.'<br />';
else
echo 'CANT DELETED'.$file.'<br />';

}
else
echo 'LIVE: '.$file.'<br />';
}




придётся выворачиваться. вешаю на страницу дополнительный код , в самом конце ("замена" крона)

   date_default_timezone_set( 'Europe/Moscow' );

$factor = 36;
//Врема жизни кэша (1 час)
$timeLifeCache = 2*$factor;

$files = glob('cache/*');

foreach($files as $file)
if(time() - filemtime($file) >= $timeLifeCache)
@unlink($file) ;


т.к. задолбался всё время держать это на контроле. размер одной кешированной странице ~50-70кб, поисковики и гости очень любят ходить по сайту.. места катострофически не хватает. (т.е. я до этого не доводил, приходилось запускать скрипт раз в 1-2 дня)


Спустя 4 минуты, 6 секунд (11.05.2012 - 13:39) Игорь_Vasinsky написал(а):
http://www.pr-cy.ru/speed_test

Домен Размер Время загрузки Средняя скорость
hdkinozavr.ru 78.7 Кб 0.13 сек 605.31 Кб/сек
kinozad.ucoz.ru 98.3 Кб 0.5 сек 196.58 Кб/сек
santalova.com 48.3 Кб 0.63 сек 76.66 Кб/сек
kino-live.org 45.8 Кб 0.36 сек 127.31 Кб/сек
hdkinomir.com 110.7 Кб 0.12 сек 922.66 Кб/сек
cinema-hd.ru 92.4 Кб 0.65 сек 142.21 Кб/сек

Спустя 2 часа, 35 минут, 22 секунды (11.05.2012 - 16:15) sebastjan написал(а):
Игорь, объясни зачем подчищать кешь, лежали бы там статичные странички и всё.
У тебя достаточно быстрый хостер по сравнению с другими.

Спустя 17 часов, 18 минут, 20 секунд (12.05.2012 - 09:33) Игорь_Vasinsky написал(а):
у меня по тарифу всего 500 Мб, но анлим сайтов и БД мускула. и дёшево относительно.

+ делается бекап БД + всего сайта. места катострафически не хватает.

подумываю для бекапа облачный какой нить заюзать, благо хостер даёт дабро для бекапа на удалённый фтп.

Спустя 19 дней, 13 часов, 51 минута, 45 секунд (31.05.2012 - 23:25) VELIK505 написал(а):
Файловый быстрее мемкеша! Не однократно проверял. Думал может я не так делаю но когда инпост мне показал свои замеры и у него файловый тоже быстрее получился.
Но тут смотря в чём. Если ты допустим кешируешь результат sql запроса какогонить большого в файл и отдаёшь. и в мемкеш то с файла получится быстрее.
А если ты опять же делаешь реал-таймовый чат и тебе надо сообщушьки раздавать постоянно из хранилищя то в таком случае мемкеш будет побыстрее. Мемкеш для динамических операций.

Спустя 2 часа, 40 минут, 4 секунды (1.06.2012 - 02:05) inpost написал(а):
VELIK505
Насчёт динамики ты прав, ведь перезаписать и добавить в файловый кеш получается дольше.
Мем-кеш плохой вариант, я так понял, что гугл использует его, но работает с ним не через ПХП, а через другие языки. А в ПХП он реализован дубово. Не зря ведь тот же facebook лишь частично берёт мем-кеш, остальное, написанное на ПХП, кеширует другим кешем в меме, который, кстати, должен будет ввестись в ПХП 6 официально smile.gif Вот с ним у меня как раз вообще одинаковые результаты, что он, что файловый.


_____________
HTML, CSS (Bootstrap), JS(JQuery, ExtJS), PHP, MySQL, MSSql, Posgres, (TSql, BI OLAP, MDX), Mongo, Git, SVN, CodeIgnater, Symfony, Yii 2, JiRA, Redmine, Bitbucket, Composer, Rabbit MQ, Amazon (SQS, S3, Transcribe), Docker
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.