Кэширование в PHP

18 May 2008 – 14:55

Уже невозможно представить современный сайт так или иначе не использующий возможностей кэширования. Создание кэша - одно из средств оптимизации, позволяющее значительно увеличить производительность работы вашего движка. Существует несколько вариантов использования механизма кэширования.

Первый вариант - использование PEAR пакета Cache_Lite для выборочного кэширования данных.
Это небольшое и простое решение позволяет кэшировать как результаты запроса, так и страницу целиком.
Сохраняем в кэше (в директории /to/cachedir/) результаты mysql запроса, время жизни устанавливаем 1 час:

  1.  
  2. require_once 'Cache/Lite.php';
  3.  
  4. $query = 'SELECT * FROM `tab`';
  5.  
  6. $cache = new Cache_Lite(array('cacheDir' => '/to/cachedir/', 'lifeTime' => 3600));
  7.  
  8. if (!($res_id = $cache->get($query))) {
  9.    $res_id = mysql_query($query);
  10.    $cache->save($res_id, $query);
  11. }
  12.  

 

  • Для вызова функции и последующего кэширования результатов ее работы можно использовать класс Cache_Lite_Function.
  • Класс Cache_Lite_Output использует функции буферизации для перехвата данных, сгенерированных PHP скриптом, и сохранят результат в кэше. Последний класс в связке с .htaccess можно легко приспособить для полного кэширования всего вывода. Не забывайте защищать каталоги с файлами кэша.

     

    Второй вариант - кэшировать байткод. Для этого подходит PECL модуль APC, который позволяет избежать трансляции одного и того же PHP кода в байткод при каждом вызове скрипта.
    Для настройки модуля правим php.ini:

    1.  
    2. extension=apc.so
    3.  
    4. [apc]
    5. apc.enabled = 1
    6. apc.shm_segments = 4
    7. apc.shm_size = 64
    8. apc.optimization = 0
    9. apc.ttl = 3600
    10. apc.user_ttl = 3600
    11. apc.num_files_hint = 1000
    12. apc.mmap_file_mask = /tmp/apc.XXXXXX
    13.  

     

    Функция для трансляции и сохранения в кэше может выглядеть так:

    1.  
    2. function compile_files($dir){
    3.   $dirs = glob($dir . DIRECTORY_SEPARATOR . '*', GLOB_ONLYDIR);
    4.   if (is_array($dirs) && count($dirs) > 0){
    5.     while(list(,$v) = each($dirs)){
    6.       compile_files($v);
    7.     }
    8.   }
    9.  
    10.   $files = glob($dir . DIRECTORY_SEPARATOR . '*.php');
    11.   if (is_array($files) && count($files) > 0){
    12.     while(list(,$v) = each($files)){
    13.       apc_compile_file($v);
    14.     }
    15.   }
    16. }
    17. compile_files('/to/cachedir');
    18.  

     

    Третий вариант позволяет кэшировать данные не на харде, а в оперативной памяти, для этого будем использовать PECL модуль memcached. Сервер memcached впервые был разработан для LiveJournal и позволил снизить загрузку серверов баз данных в разы.
    Пример использования:

    1.  
    2. $id = (int) $_GET['id'];
    3.  
    4. $memcached = new Memcache;
    5. $memcached->connect('hostname', 11211);
    6.  
    7. if (!$row = $memcached->get('id_' . $id)){
    8.    $res = mysql_query('SELECT * FROM post WHERE post_id = ' . $id);
    9. if ($res && mysql_num_rows($res) > 0){
    10.    $row = mysql_fetch_assoc($res);
    11.    $memcached->set('id_' . $id, $row, MEMCACHE_COMPRESSED, time() + 3600);
    12. }}
    13.  
    1. комментарии (2) to “Кэширование в PHP”

    2.   Дмитрий Ожегов -- Jun 16, 2008

      Точно так же и я делаю))))))))


    3.   Вячеслав -- Jan 3, 2009

      Alex, если я правильно понимаю, то 2-ой вариант может использоваться независимо от 1-го и 3-го - это оптимизация самого PHP.

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

      Т.е. если я правильн понимаю, то самым быстрым будет использование 2-го варианта в связке с 3-им.

      Сейчас есть сложный проект, где хочу попробовать использовать memcache. Проект на VDS с небольшим количеством операционной памяти (~ 100 Mb).

      Как вы считаете есть ли при таком раскладе смысл использовать быстрый memcache (боюсь переполенния оперативки) или лучше кэшировать в файловой системе?


    Комментировать