Кэширование на PHP
Кэширование данных - это особая технология, направленная на снижение нагрузки на сервер. Суть ее заключается в том, что динамический контент, выбранные из базы данные или данные, получаемые из сторонних источников, сохраняются на диске в виде обычного текстового файла или в памяти вашего сервера. Когда они потребуются снова, то уже нет необходимости опять выполнять тяжелый запрос к базе, обращаться к стороннему серверу или заново парсить шаблон страницы, достаточно просто прочитать эти данные из ранее сохраненного файла или из памяти. Такой подход позволяет значительно ускорить генерацию страниц и тем самым ускорить загрузку сайта, что немаловажно на нагруженных проектах. Актуальность закэшированных данных устанавливается параметром "жизни кэша", то есть интервалом времени от момента сохранения данных до момента, когда их требуется обновить. "Время жизни" определяется для каждого типа данных индивидуально. Так, например, текст статьи может больше никогда не меняться после опубликования, поэтому ее закэшированный вариант можно также никогда не обновлять, кэш с комментариями может обновляться по мере добавления комментариев, данные пузомерок Google PR и Яндекс тИЦ достаточно обновлять раз в сутки, а картинку счетчика посещений желательно перерисовывать с интервалом не реже 10 минут.Сейчас мы попробуем написать свой модуль для работы с кэшем, основанный на файлах, чтобы понять как это все работает. Функции будут очень простые:
Code (PHP) : Убрать нумерацию
- // Определить папку для хранения кэшированных данных
- define ('CACHE_DIR',dirname(__FILE__).'/cache');
- // Запись данных в кэш
- function save_cache($file, $data) {
- if ($f=fopen(CACHE_DIR.'/'.$file,'w')) {
- fwrite($f,serialize($data));
- fclose($f);
- return true;
- }
- else {
- return false;
- }
- }
Code (PHP) : Убрать нумерацию
- // Чтение данных из кэша
- function load_cache($file, $expire_time=0) {
- $fname=CACHE_DIR.'/'.$file;
- // Проверка наличия файла
- if (file_exists($fname)) {
- if ($expire_time) {
- // Проверка актуальности файла
- if ((time()-filemtime($fname))>=$expire_time) {
- return false;
- }
- }
- // Прочитать данные
- if ($f=fopen($fname,'r')) {
- $tmp=fread($f,filesize($fname));
- fclose($f);
- return (unserialize($tmp));
- }
- else {
- return false;
- }
- }
- else {
- return false;
- }
- }
Функции для работы с кэшем у нас есть, можно применить их на конкретных примерах. Первый пример - чтение из базы данных. Время "жизни кэша" в этом примере равно 10 минутам (время передается в секундах).
Code (PHP) : Убрать нумерацию
- // Запрос к базе данных
- $query="SELECT `fucking_huge_data` FROM `big_slow_table`";
- // Имя файла с закэшированными данными
- $file=md5($query);
- // Попробовать загрузить данные из кэша, актуальность = 10 минут
- $res=load_cache($file, 10*60);
- // Данные не загрузились или устарели, читаем их из базы
- if ($res===false) {
- $sql_result=mysql_query($query);
- $res=array();
- while ($tmp=mysql_fetch_array($sql_result)) {
- $res[]=$tmp;
- }
- // Сохранить данные в кэш
- save_cache($file,$res);
- }
- // Операции с прочитанными или загруженными данными
- ...
Code (PHP) : Убрать нумерацию
- // Имя файла для хранения закэшированной страницы
- $file=md5(getenv('REQUEST_URI'));
- // Загрузить страницу из кэша
- $content=load_cache($file);
- if ($content) {
- echo $content;
- exit;
- }
- // Начать буферизацию
- ob_start();
- echo "<html>";
- echo "<head>";
- echo " <title>Кэшированная страница</title>";
- echo "</head>";
- echo "<body>";
- echo "Эти данные закэшированы ".date('d.m.Y H:i.s')."<br>";
- echo "переданные параметры:";
- echo "<pre>";
- echo print_r($_GET,true)."</pre>";
- echo "</body>";
- echo "</html>";
- // Получить страницу из буфера
- $content=ob_get_contents();
- // Сохранить данные в кэш
- save_cache($file,$content);
- // Отправить страницу в браузер и очистить буфер
- ob_end_flush();
Использование подобной технологии на этом сайте позволило мне уменьшить нагрузку на базу до 2-3 запросов на страницу, а в некоторых случаях и вообще не задействовать базу. Также значительно повысилась скорость генерации страниц из шаблонов.
В зависимости от объемов обрабатываемой информации, размер кэша может очень быстро расти. Чтобы этого избежать, рекомендуется сделать какой-нибудь скрипт для уборки мусора. Он будет запускаться по планировщику и принудительно удалять файлы, к которым, например, не обращались более суток. И не забывайте о безопасности, обязательно закройте директорию с кэшем от несанкционированного доступа.
Для проектов с большой нагрузкой лучше обратить внимание на nginx и Memcached, но это совершенно другая история. А для небольших сайтов вполне сгодится описанный в статье метод.
Просмотров: 6523 | Комментариев: 11
Метки: PHP
Внимание! Статья опубликована больше года назад, информация могла устареть!
Комментарии
Отзывы посетителей сайта о статье
fag
(03.07.2013 в 20:46):
Не получается через echo. Через var_dump выводит вот такое array(1) { [0]=> array(64) { [0]=> string(3) "498" ["id"]=> string(3) "498" [1]=> string(1) "2" и так далее... через echo $res[0] выводит Array
ManHunter
(03.07.2013 в 20:19):
Можно так http://www.php.net/manual/ru/f...ion.echo.php Все зависит от данных.
fag
(03.07.2013 в 19:42):
// Операции с прочитанными или загруженными данными
...
И вот как вывести эти данные?
...
И вот как вывести эти данные?
saddam
(14.01.2013 в 01:51):
Можете ли вы помочь в работе системного кэша на страницу моего сайта
ManHunter
(19.03.2012 в 21:02):
Я пишу только о том, что использую сам и о том, что мне интересно. memcached у меня никаких эмоций не вызывает.
Дмитрий
(19.03.2012 в 20:57):
ManHunter, по запросу "Кэширование на PHP" аналогичная картина, но вы же о нём написали
ManHunter
(19.03.2012 в 01:08):
Поисковики по запросу "memcached" выдают кучу информации на любых языках и для любого уровня знаний.
Дмитрий
(19.03.2012 в 00:15):
Было бы интересно почитать о работе с memcached
Станислав
(01.03.2012 в 20:28):
Большое спасибо за обзор, помница я наверное даже просил про это в чате) сейчас зашёл и вот оно, главное написано понятным языком, вам бы в школе преподавать)))
morgot
(01.03.2012 в 17:53):
Спасибо за интересную статью. В который раз уже нахожу у вас в блоге то, что нет нигде, и очень актуально.
Добавить комментарий
Заполните форму для добавления комментария
// Данные не загрузились или устарели, читаем их из базы
if ($res===false) {
$sql_result=mysql_query($query);
$res=array();
while ($tmp=mysql_fetch_array($sql_result)) {
$res[]=$tmp;
}
// Сохранить данные в кэш
В строке $res[]=$tmp; убираем [], и тогда все нормально выводится