Алгоритм кэширования для PHP и не только
Как известно, кэширование различных данных — отличный способ повышения производительности приложений. Как под Web, так и не только. При этом кэшироваться могут как данные, так и готовые результаты. Сегодня мы рассмотрим один из вариантов алгоритма кэширования, пример будет на PHP и с уклоном под Web, но суть одна для всех языков программирования.
Итак, у нас есть необходимость кэшировать определенные данные. Например, сводную статистику по пользователям некой социальной сети: сотни позиций, десятки графиков — все это требует значительных вычислительных способностей. При этом генерировать необходимые данные каждый раз, когда к ним обращаются в данном случае очень накладно. Лучше всего брать эти данные уже в готовом виде из заранее подготовленного кэша, который обновлять с некой периодичностью для поддержания его данных в актуальном состоянии.
Но по какому событию производить обновление данных в кэше? Чаще всего в этих целях применяют Cron. Крон — это специальный демон в системах наподобие Unix ОС, с помощью которого можно выполнять указанные задания в определенное время или с определенным интервалом. Так в нашем случае, мы можем, например, раз в 5 минут вызывать скрипт, который будет обновлять данные в кэше. Но это не единственное решение, и не всегда наиболее оптимальное.
Почему он не всегда удобен? Есть масса случаев. Начиная от того, что вы можете пользоваться простым виртуальным хостингом, на котором не предусмотрена поддержка планировщика задач Cron. И заканчивая тем, что если у вас очень много различных заданий, помещать их все в crontab (специальный файл со списком заданий и параметров для Cron для каждого пользователя в системе) может быть крайне неудобно. Что же делать? Выход просто — помещать в кэш некие дополнительные данные, на основе которых мы сможем судить об актуальности его данных.
Проще всего это реализовать, добавив в кэш данные о дате его создания. Например, если наш кэш хранится в файле, то функция, которая генерирует его содержимое, может выглядеть примерно так:
<?php
function create_my_cache()
{
$now = time();
$my_cache_content = '<?php
if (!defined(\'MY_CACHE_TIME_CREATE\'))
define(\'MY_CACHE_TIME_CREATE\', '.$now.'); ?>';
//далее мы добавляем к переменной
//собственно сам кэш и сохраняем
//ее в файле нашего кэша
}
?>
Таким образом, когда мы подключим файл нашего кэша, мы получим константу MY_CACHE_TIME_CREATE, которая будет содержать время создания данного кэш файла. Для чего мы проверяем, не объявлена ли уже данная константа? Ответ на этот вопрос будет чуть дальше.
Все, что нам остается сделать — это проверить, не устарели ли данные нашего кэша. Итак, пусть где-то в конфиге у нас декларируется константа MY_CACHE_LIFETIME, которая содержит время актуальности нашего кэша (в секундах). Например, так для 5 минут:
<?php define('MY_CACHE_LIFETIME', 60*5); ?>
Теперь мы подключаем наш файл с кэшем:
<?php
$now = time();
@include '/cache/my_chache_file.php';
if (
!defined('MY_CACHE_TIME_CREATE')
||
(($now - MY_CACHE_TIME_CREATE) > MY_CACHE_LIFETIME)
)
{
//обновляем кэш в файле
create_my_cache();
//обновляем подключенный кэш
@include '/cache/my_chache_file.php';
}
?>
Как видим все просто. Мы подключаем файл с кэшем и проверяем, не устарел ли наш кэш, основываясь на разнице текущего и времени генерации кэша по отношению к заданной нами MY_CACHE_LIFETIME. Так же мы проверяем, объявлена ли вообще константа MY_CACHE_TIME_CREATE — это повысит уровень нашего кода т.к. он сможет работать без предварительной инициализации после установки или переноса, и вообще станет более универсальным. Как теперь ясно, в самом кэше мы проверяем, объявлена ли данная константа для того, чтобы избежать ошибки, которая возникнет в случае обновления данных в кэш файле (в этом случае происходит повторный его инклуд, и, соответственно попытка повторного объявления уже объявленной константы).
Вот и все. Как видите, все достаточно просто, элегантно и функционально. Конечно, по своему усмотрению, константы вы можете заменять переменными, это несколько упростит код, однако не забывайте в таком случае про обеспечение рабочей области видимости ваших переменных. Так же, если у вас в кэше, к примеру, не присваиваются необходимые данные, а происходит вывод готового html-кода, вам необходимо обрамить его проверкой, аналогичной проверке при инклуде кэша:
<?php
if (
!defined('MY_CACHE_TIME_CREATE')
||
(($now - MY_CACHE_TIME_CREATE) > MY_CACHE_LIFETIME)
)
{
//html...
}
?>
Ну, вообще говоря, случаев может быть огромная разновидность. Я вам показал лишь самый простой, обобщенный вариант, в котором отображена главная суть — обновление кэша по мере потребности, с применением даты его создания. В сравнении с Cron и прочими решениями для подобных задач, у данного варианта есть целый ряд преимуществ, которые вы откроете для себя во время его применения. Удачи!
© http://www.ru-coding.com/
Условия использования материалов сайта.
|