Как сделать кэш php

Обновлено: 08.07.2024

Кэширование — это один из способов ускорить ваш код. Смысл любого кэширования состоит в том, чтобы организовать некий буфер, в котором будет храниться уже готовый результат выполнения: то есть вместо выполнения кода, будет отданы данные из кэша.

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

Совершенно бессмысленно создавать кэш для функций, которые редко вызываются в коде. В этом случае затраты на кэширование просто не «окупаются».

Существует два основных подхода к организации кэша: в файле и в памяти.

Скажем, есть некая функция, которая выполняет какой-то сложный расчёт. Эта функция вызывается много раз. Для того, чтобы избежать повторного выполнения, результат сохраняется в статическую переменную. Примерно так:

Если функция имеет входящие аргументы, которые влияют на итоговый результат, то кэшируется не вся функция, а лишь самый ресурсоёмкий участок кода.

Иногда нужно создать кэш, который будет использован несколькими функциями. В этом случае, вместо статичной переменной используют глобальную.

В ООП действуют аналогично, только вместо глобальной переменной применяют singleton/multiton с паттерном Registry.

Кэш в памяти — достаточно простой вариант для реализации. Если вы уже перешли на PHP 7, то учитывайте, что в этой версии очень здорово доработали оптимизацию, поэтому перед доработкой функций, убедитесь, что её выполнение действительно затратно (например с помощью функций профилирования).

Другой вид кэша — файловый. Он позволяет хранить результаты достаточно долго. В таком кэшировании вместо выполнения кода, отдаётся результат из файла-хранилища.

Например вы реализуете функцию, которая работает с csv-файлом: его получение, обработка, проверка и результат помещается в массив, который передаётся уже дальше по коду. Это затратные операции, поэтому полученный массив нужно сохранить в файл. Здесь не имеет смысла применять static-кэш, поскольку функция будет срабатывать для каждого посетителя сайта. Если же мы сохраним в файл, то обработка произойдёт только один раз.

Лучшим способом для хранения php-данных в файле — сериализация. Также можно использовать формат JSON — это для случаев, если нужно сделать кэш читаемым.

Файловый кэш может быть каким-то «глобальным», как например в MaxSite CMS, или «локальным», скажем на уровне шаблона — где задаётся какой-то фиксированный файл кэша определенной функции. «Глобальный» вариант реализуется достаточно просто — есть функции, которые либо добавляют, либо возвращают данные из кэша. Как именно он организован уже не имеет значения.

«Локальный» вариант обычно реализуется по такому алгоритму.

  • Проверяется существование файла кэша.
  • Если он есть, то он считывается и деселиализуется.
  • Если нет, то выполняется участок кода, результат которого сериализуется и записывается в файл кэша.

При необходимости в такую функцию можно добавить ещё и static-кэширование. Это при условии, что обработка данных также ресурсозатратно. То есть смотреть по ситуации.

Кэширование вывода базируется на предыдущих вариантах и используется, когда даже нет смысла выполнять функции. То есть формируется готовый для вывода html-код, он загоняется в кэш (обычно файловый) и потом просто отдаётся как есть. Это самый быстрый в мире кэш. (Кто в курсе, то именно так работает мой maxcache для вп — он формирует кэш из готовых страниц так, что вп даже не запускается.)

Для организации такого кэша используется буферизация вывода.

Такой кэш самый эффективный, но его использование будет оправдано для достаточно больших кусков html-кода. При этом нужно учитывать, что в кэш может попасть содержимое индивидуальное для каждого посетителя, например ссылка на профиль. То есть кэш должен учитывать такие ситуации. В MaxSite CMS по этому принципу работает плагин global_cache, где проверяется залогиненность посетителя: если она есть, то кэш для него не работает.

PS Вы можете подписаться а мой telegram-канал, где я рассказываю о PHP, MaxSite CMS и т.п. На сайте они публикуются.

Ни для кого не секрет, что чем быстрее загружается сайт тем удобнее на нем будет пользователям. Если страницы загружаются быстро пользователи не будут уходить из вашего сайта и поисковики будут относиться к сайту лучше. Для многих современных сайтов узким местом становиться движок выполнения динамических скриптов PHP.

Веб-сервер Nginx при правильной настройке может отдавать просто огромное количество страниц мгновенно, чего нельзя сказать про PHP на генерацию страницы может уходить до нескольких секунд. Но PHP тоже можно ускорить с помощью кэширования. В этой статье мы рассмотрим как настраивается кэширование php, каким оно бывает и зачем вообще это нужно. Для примера будем использовать связку php-fpm и Nginx, но информация из статьи подойдет и для других вариантов установки.

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

Особенность интерпретируемых языков в том, что при каждом запуске скрипта интерпретатор должен скомпилировать программу и проверить ее на ошибки. Но мы можем обойти. Есть два основных вида кэширования:

  • Кэширование готовых страниц - страница генерируется php, а потом пользователю отдается готовая страница без обращения к php. Я расскажу как это сделать через fastcgi, но не рекомендую применять такой метод для wordpress или других движков, их лучше кэшировать с помощью специальных плагинов;
  • Кэширование байт кода и инструкций - а это уже интересно, кэшируется не вся страница, а только некоторые инструкции, и куски байт кода, которые не изменяются при вызовах скрипта. Перед тем как выполнять скрипт, интерпретатор должен преобразовать его в понятный для него формат, при кэшировании такое преобразование выполняется только первый запуск, а дальше берется версия из кэша;
  • Кэширование сессий - по умолчанию php сохраняет сессии пользователей в файлы и мы можем немного ускорить его работу, если будем сохранять сессии в оперативную память.

Дальше рассмотрим более подробно, как настроить каждый вид кэширования для вашего сервера. Начнем с кэширования opcode php.

Кэширования байткода в PHP

Начиная с PHP 5.5 в интерпретатор языка была добавлена поддержка кэширования байткода из ZendFramework. В новых версиях этот кэш позволяет очень сильно увеличить производительность вашего ресурса, например, есть сведения, что на PHP 7 Wordpres и другие движки работают чуть ли не в два раза быстрее. Перед тем как настраивать кєширование opcode php, нужно установить его пакет:

sudo apt install php-opcache

Или для Red Hat дистрибутивов:

sudo yum install php-opcache

Затем, чтобы включить кэширование нужно добавить несколько строк в php.ini, можно также создать отдельный файл в /etc/php/conf.d/


Рассмотрим что означают эти строки, чтобы вы знали какие значения установить. Первая строка загружает расширение, здесь ничего менять не нужно.

  • opcache.error_log - указывает файл для записи лога ошибок, будет полезно при отладке;
  • opcache.log_verbosity_level - указывает насколько подробным должен быть лог файл, значение от 1 до 4;
  • opcache.enable - включает кэширование;
  • opcache.enable_cli - включает кэширование страниц php для консольной версии;
  • opcache.memory_consumption - количество оперативной памяти для хранения кэша;
  • opcache.max_accelerated_files - число скриптов/файлов, которые нужно кэшировать;
  • opcache.validate_timestamps - проверять время изменения данных в файле скрипта;
  • opcache.revalidate_freq - частота проверки для предыдущего параметра;
  • opcache.revalidate_path - установите в 0 чтобы выполнять проверку при include только первый раз;
  • opcache.enable_file_override - кэширует запросы к атрибутам файлов, например, существование и т д;
  • opcache.blacklist_filename - список файлов, которые не нужно кэшировать;
  • opcache.max_file_size - максимальный размер файла скрипта для кэширования, 0 - не ограниченно;
  • opcache.interned_strings_buffer - допустимое количество строк в буфере;
  • opcache.fast_shutdown - использовать быстрый способ освобождения памяти.

После сохранения всех настроек вам останется только перезапустить php или ваш веб-сервер:

systemctl restart php-fpm

Для того чтобы убедиться, что все работает вы можете захотеть посмотреть какие скрипты уже закэшированы. Для этого можно использовать скрипт opcache-status. Просто сохраните скрипт в директорию веб-сервера, а затем дайте ему права:

Дальше можно открыть скрипт в браузере для просмотра статистики:


Здесь можно видеть подробную статистику по кєширвоанию, настройки и количество занятой памяти.

Хранение сессий в memcached

По умолчанию php хранит сессии в файловой системе, в некоторых случаях, вы можете достаточно сильно ускорить работу php, если перенесете хранение сессий из файлов в оперативную память, например, memcached. Сначала нужно установить memcached и php библиотеку для работы с ней:

sudo apt install memcached php-memcached

Или для систем на базе Red Hat:

sudo yum install memcached php-memcached


Сначала нам нужно настроить memcached, откройте файл /etc/sysconfig/memcached и найдите строку CACHESIZE, здесь нужно указать объем оперативной памяти, которая выделяется под кэш:


Дальше осталось указать php использовать memcached для хранения сессий:

session.save_handler = memcache
session.save_path = "tcp://localhost:11211"


Осталось перезапустить ваш php интерпретатор:

systemctl restart php-fpm

Если вы хотите проверить все ли правильно кэшируется и есть ли вообще что-либо в кэше, можно использовать phpmemcacheadmin.

Кэширование страниц fastcgi

Я не советую использовать кэширование fastgci для сайтов WordPress, потому что там есть специальные плагины, которые могут точно контролировать кэш, очищать его когда нужно и вовремя обновлять. Но во всех остальных случаях кэш fastcgi может очень сильно ускорить работу сайта. Настраивается он в конфиге, где вы включаете fastgci, например, в конфигурации веб-сервера Nginx. Минимально для настройки кэша fastgci достаточно добавить в блок server такие строки:

fastcgi_cache_path /var/nginx/cache levels=1:2 keys_zone=MYAPP:100m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";

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

Теперь нужно настроить блок обработки php:

\.php$ fastcgi_pass unix:/var/run/php7-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_cache MYAPP;
fastcgi_cache_valid 200 60m;
>

Здесь мы обращаемся к уже настроенной зоне памяти MYAPP, а также указываем время жизни кэша в один час. Для проверки кэширования можно посмотреть содержимое папки:

ls -lR /var/nginx/cache/

С помощью таких методов ваши страницы будут загружаться намного быстрее. Если вам понадобится отключить кєширование php для отдельных страниц, то сначала создаем переменную no_cache со значением 0:

Затем проверяем нужные параметры, и если соответствует, то устанавливаем значение в 1:

if ($request_method = POST)
set $no_cache 1;
>

И на завершение передаем значение этой переменной таким директивам, это отключит кэширование когда не нужно:

fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;


Не забудьте перезапустить Nginx перед тем как проверять:

systemctl restart nginx

Выводы

В этой статье мы рассмотрели как настроить кэширование php скриптов, разобрали виды кэширования, кэширование opode php, а также как все это работает. Надеюсь, эта информация была полезной для вас.

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

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

Кэширование — это сохранение данных в высоко доступных местах на временной основе для того, чтобы их можно было получать быстрее, чем из оригинального источника. Самый распространенный пример применения кэша — получение данных из базы. При первом получении, допустим, продукта из базы данных, он сохраняется в кэш на определённое время, поэтому каждый следующий запрос к этому продукту уже не будет тревожить БД: данные будут получены из другого хранилища.

Какие бывают подходы?

Существует множество подходов к кэшированию. Список совместимых с PHP инструментов можно посмотреть на странице PHP-cache. Самые распространенные из них:

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

Один из самых распространённых и простых в настройке инструментов кэширования, сохраняет нужные нам данные в оперативную память. (Ещё умеет кэшировать промежуточный код, но это уже совсем другая история) Чтобы начать работу с APCu, необходимо убедиться, что он установлен. Для этого в командной строке запустите следующую команду:

Другой способ проверки: создайте файл index.php и поместите в него вызов функции phpinfo(). Убедитесь, что у вас настроен веб-сервер для используемой директории и откройте скрипт в браузере через адрес сервера. Нас интересует секция APCu: если внутри неё есть пункт APCu Support: Enabled, значит всё хорошо, мы можем идти дальше.


Если APCu у вас не установлен, сделать это можно следующим способом:

  1. Запустите окно терминала (Linux/MacOS) или командную строку (Windows. Введите в поиске "cmd").
  2. Выполните команду:

3. Откройте в любом текстовом редакторе файл конфигурации php.ini и убедитесь в наличии следующих строк:

  1. Если указанных строк нет, добавьте их и сохраните файл конфигурации.
  2. Повторите проверку наличия установленного APCu.

Для использования этого подхода кэширования нам понадобятся основные функции. Вот пример их применения:

Любой кэш работает по принципу key-value хранилища: это значит, что данные сохраняются со специальным ключом, по которому и происходит обращение. В данном случае ключ хранится в переменной $cacheKey.

Важно! Этот подход работает только при работе в режиме веб-сайта, то есть при запуске из командной строки вы не будете получать данные из кэша, а всё, что вы в него сохранили, будет очищено по завершению работы скрипта. Однако это не вызовет никаких ошибок.

Array-кэш

Более простой, но не всегда применимый метод кэширования. Если APCu сохраняет данные и делает их доступными для последующих выполнений всеми процессами, то Array-кэш хранит их только в рамках обрабатываемого запроса.

Из-за своей ограниченности этот подход применяется редко, однако знать о нём полезно.

Memcached и Redis

Наиболее продвинутые подходы кэширования. Подразумевают наличие запущенного отдельно сервера Memcached или Redis. Из PHP мы подключаемся к этому серверу по адресу и порту. Конфигурация этих решений сложнее, чем настройка APCu, но метод хранения данных очень похож: оперативная память. Самыми главными их преимуществами являются

В этой статье мы не будем вдаваться в подробности настройки Memcached и Redis. На этом этапе нам важно помнить, что, если нагрузка очень высокая, нам следует смотреть в сторону именно этих решений, так как они имеют хороший потенциал к масштабированию.

Стандарт PSR-16

В PSR есть два стандарта, посвящённых кэшированию: PSR-6 (обычный интерфейс кэширования) и PSR-16 (простой интерфейс кэширования) — мы сосредоточимся на PSR-16.

Этот стандарт предлагает специальный интерфейс (CacheInterface), которому могут удовлетворять классы, выполняющие функцию кэширования. Согласно ему, такие классы должны реализовывать следующие методы:

  • get($key, $default) — получение данных из кэша: вторым аргументом передаётся значение, которое будет возвращено в случае отсутствия этих данных;
  • set($key, $value, $ttl = null) — сохранение данных в кэш: как мы уже видели ранее, третьим параметром передаётся время хранения в секундах. Если оставить его пустым (null), значение будет подставлено по умолчанию из конфигурации кэша;
  • delete($key) — удаляет данные по ключу;
  • clear() — очищает все хранилище;
  • getMultiple($keys, $default) — позволяет получить данные сразу по нескольким ключам;
  • setMultiple($values, $ttl = null) — позволяет записать сразу несколько значений. В качестве $value мы передаем ассоциативный массив, где ключ — $key для кэша, а значение — данные для сохранения;
  • deleteMultiple($keys) — удаляет данные по нескольким ключам;
  • has($key) — проверяет наличие данных по ключу.

Как вы можете заметить, интерфейс очень прост, и даже тех функций, что мы рассмотрели в примере с APCu, достаточно для того, чтобы написать свой сервис кэша в соответствии с PSR-16. Но зачем это нужно?

Главные преимущества соблюдения стандартов PSR заключаются в том, что

  • они поддерживаются большинством популярных библиотек;
  • многие PHP-программисты придерживаются PSR и с легкостью освоятся в вашем коде;
  • благодаря интерфейсу, мы можем легко подменять используемый сервис на любой другой, поддерживающий PSR-16.

Давайте подробнее рассмотрим последний пункт и его преимущества.

Подключение PSR-16 библиотек

Библиотеки, создающие «обертку» над существующими инструментами кэширования для соответствия интерфейсу называются адаптерами. Для примера, рассмотрим адаптеры тех методов, что мы уже обсудили:

Все они удовлетворяют PSR-16 и поэтому применяются одинаково, однако логика «под капотом» у каждого своя.

Для примера давайте загрузим APCu- и Array-адаптеры в наш проект с помощью Composer.

Давайте представим, что у нас есть специальный класс для получения продуктов из базы данных. Назовем его ProductRepository, у него есть метод find($id), который возвращает продукт по его идентификатору, а если такого продукта нет — null.

Если мы хотим подключить кэширование, мы не должны делать это внутри репозитория, потому что его ответственность — возвращать данные из базы данных. Куда же мы тогда добавим кэш? Есть несколько популярных решений, самое простое — дополнительный класс-провайдер. Всё, что он будет делать — пробовать получить данные из кэша, а если это не получится — обратится в репозиторий. Для этого в конструкторе такого класса определим две зависимости — наш репозиторий и CacheInterface. Почему именно интерфейс? Потому что так мы сможем использовать абсолютно любой из упомянутых адаптеров или других классов, удовлетворяющих PSR-16.

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

Если же мы захотим, заменить APCu-кэширование на Array-адаптер или любой другой, мы просто передадим новый подход в провайдер вместо старого, потому что все они реализуют CacheInterface.

Состояние гонки и обновление данных

Кэш работает до тех пор, пока мы содержим его в актуальном состоянии. Это значит, что, если пользователь хочет обновить продукт, то продукт должен обновиться и в базе данных, и в нашем кэше. Однако здесь есть один важный нюанс.

Представим, что нашим проектом пользуется очень большое количество пользователей, и двое из них одновременно обновляют одну и ту же сущность. В этом случае, может возникнуть такая ситуация:

  • пользователь 1 получил сущность из кэша;
  • пользователь 1 обновил сущность в БД;
  • пользователь 2 получил сущность из кэша;
  • пользователь 1 обновил данные в кэше;
  • пользователь 2 обновил сущность в БД, но перезаписал её старыми данными, потому что сущность была неактуальна на момент получения и т. д.

Такая ситуация называется состоянием гонки, когда несколько процессов обращаются одновременно к одному и тому же ресурсу, и может возникнуть конфликт версий. Чтобы избежать такой проблемы, следует придерживаться одного простого правила:

Когда вы получаете любую сущность в коде с целью её обновления, всегда используйте данные из БД.

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

Вы можете либо обращаться в нужных местах к ProductRepository вместо ProductDataProvider, либо добавить аргумент к методу DataProvider. Например, такой ($fromCache):

Заключение

Кэширование требует от разработчика дополнительных усилий при разработке проекта, и его применение не всегда может быть целесообразно. Решение применять его или нет должно быть основано на предполагаемой (или фактической) нагрузке и ваших ожиданиях от скорости отклика пользователю.

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

Кеширование промежуточного кода (Opcode Caching)
Кэширование кода это один из самых легких и эффективных путей увеличения производительности в PHP. Использовании данного вида кэширования позволит избавиться от большого количества неэффективностей, возникающих при процессе запуска выполнения кода. Кэширование кода сохраняет промежуточный код в памяти для того чтобы не компилировать PHP-код каждый раз при запуске файла.

Существует множество библиотек для такого кэширования, например, APC, XCache, eAccelerator и Zend Platform.

Кэширование промежуточного кода файлов
Когда у нас есть большое количество кода и наш сервис отличается большой посещаемостью, скорее всего мы не будем ждать, когда каждый PHP-файл будет обработан при его вызове, логично в этом случае запустить некий скрипт перед выкладкой кода на сервера, который сразу создаст промежуточный код. Например, код такого скрипта может быть реализован так

/**
* Compile Files for APC
* The function runs through each directory and
* compiles each *.php file through apc_compile_file
* param string $dir start directory
* return void
*/
function compile_files($dir)
$dirs = glob($dir. DIRECTORY_SEPARATOR. '*', GLOB_ONLYDIR);
if (is_array($dirs) && count($dirs) > 0)
while(list(,$v) = each($dirs))
compile_files($v);
>
>
$files = glob($dir. DIRECTORY_SEPARATOR. '*.php');
if (is_array($files) && count($files) > 0)
while(list(,$v) = each($files))
apc_compile_file($v);
>
>
>
compile_files('/path/to/dir');

Кэширование переменных
Большинство библиотек кэширования позволяет кэшировать значения переменных. Очень полезно сохранять значения конфигурации или данные, которые сложно вычислить (получить) и которые не меняются (возможно не меняются в течение некоторого времени, тогда на базе такого кэширования можно реализовать кэширование с устареванием, примечание переводчика).

if (!$config = apc_fetch('config'))
require('/path/to/includes/config.php');
apc_store('config', $config);
>

Практический пример иллюстрируется на базе использования Zend Framework и простого запуска утилиты ab, в данном примере результат XML-конфигурации сохраняется в кэше. Ускорение времени разбора позволяет экстремально быстро получить доступ к параметрам конфигурации.
Код:
if (!$conf = apc_fetch('pbs_config'))
$conf = new Zend_Config_Xml(PB_PATH_CONF. '/base.xml', 'production');
apc_store('pbs_config', $conf);
>
Concurrency Level: 5
Time taken for tests: 30.33144 seconds
Complete requests: 684
Failed requests: 0
Write errors: 0
Concurrency Level: 5
Time taken for tests: 30.12173 seconds
Complete requests: 709
Failed requests: 0
Write errors: 0

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

Файловое кэширование результатов
В некоторых случаях сервер обрабатывает запросы, результатом которых является одинаковый контент. Есть возможность закэшировать подобные вид контента (полностью или его часть)
В данном тексте иллюстрируется пример на основе пакета Pear::Cache_Lite.

Полное кэширование вывода
Полное кэширование довольно тяжело выполнить на большинстве сайтов с постоянно обновляющимися данными из большого количества источников. Все это правда, однако, нет необходимости обновлять данные каждую секунду. Даже 5-10 минутная задержка при экстремально высокой загрузке сайта позволит вам увеличить производительность.
Пример ниже, сохраняет слепок страницы для будущего использования. Такой подход может помочь большому количеству пользователей.
Я не рекомендую использовать данное решение, но если вам нужно что-то быстрое, вы можете его использовать, рано или поздно вы увидите недостатки этого метода.
The Bootstrap Cache Example:

require('/path/to/pear/Cache/Lite/Output.php');
$options = array(
'cacheDir' => '/tmp/',
'lifeTime' => 10
);
$cache = new Cache_Lite_Output($options);
if (!($cache->start($_SERVER['REQUEST_URI'])))
require('/path/to/bootstrap.php');
$cache->end();
>

.htaccess
php_value auto_prepend_file /path/to/cache_start.php
php_value auto_append_file /path/to/cache_end.php
cache_start.php
require('Cache/Lite/Output.php');

$options = array(
'cacheDir' => '/tmp/',
'lifeTime' => 10
);
$cache = new Cache_Lite_Output($options);
if (($cache->start($_SERVER['REQUEST_URI'])))
exit;

Cache Lite делает большинство тяжелой работы такой как блокирование файла, решение как сохранять контент для различных параметров (в данном примере используется REQUEST URI). Вам также может быть необходимы значения $_POST, $_COOKIE и $_SESSION.

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


Пока это чересчур упрощенный пример, он только показывает гибкость сохранения значения. Вы можете сохранять значения массивов для того чтобы обращаться к ним позже.
Кэширования значения массива
require('Cache/Lite.php');
$options = array(
'cacheDir' => '/tmp/',
'lifeTime' => 3600, //1 hour
'automaticSerialization' => true
);
$cache = new Cache_Lite($options);
if (!($categories = $cache->get('categories')))
$rs = mysql_query('SELECT category_id, category_name FROM category');
$categories = array();
while($row = mysql_fetch_assoc($rs))
$categories[] = $row;
>
$cache->store($categories, 'categories');
>
var_dump($categories);

Как вы видите, вы можете сохранять в кэше различные типы данных. Однако, использовать файловое кэширования я бы не рекомендовал для сохранения результатов запросов к базе данных.

Кэширование в оперативной памяти
Существует множетсво путей для того чтобы произвести кэширование в памяти: memcached, memory tables в базах данных, RAM disk и другие.
Memcached
С сайта memcache memcached это высокопроизводительная и распределенная кэширующая система, которая увеличивает скорость динамических веб-приложений путём снижения загрузки с базы данных.
О чем это говорит, о том, что можно сохранить данные на одном сервере, к которому будут обращаться другие сервера, это не зависит от вашего веб-сервера (как в случае кеширования промежуточного кода), так как memcached – это демон, который в большинстве случаев используется для кэширования результатов запросов к базам данных.
Пример работы с Memcache:

$post_id = (int) $_GET['post_id'];
$memcached = new Memcache;
$memcached->connect('hostname', 11211);
if (!$row = $memcached->get('post_id_'. $post_id))
//yes this is safe, we type casted it already ;)
$rs = mysql_query('SELECT * FROM post WHERE post_id = '. $post_id);
if ($rs && mysql_num_rows($rs) > 0)
$row = mysql_fetch_assoc($rs);
// cache compressed for 1 hour
$memcached->set('post_id_'. $post_id, $row, MEMCACHE_COMPRESSED, time() + 3600);
>
>
var_dump($row);

Это довольно простой пример работы с memcached. Мы сохранили простой элемент в памяти для будущего использования, до которого в будущем получим лёгкий доступ. Я рекомендую использовать данный метод для данных, к которым вы чаще всего будете обращаться.
Пример настройке параметров сессий для работы с Memcache
session.save_handler = memcache
session.save_path = «tcp://hostname:11211»

Как вы видите поддержка сессий довольно таки простая. Если у вас много серверов memcached переменная save_path должна содержать названия серверов через запятую with each server.
Memory Tables баз данных
Memory tables баз данных могут быть использованы для хранения данных сессии. Вы можете создать таблицу такого типа используя MySQL. Создайте ваш собственный обработчик сессий. Это один из способов увеличить производительность сессий.
RAM Disk
В то время как подход использования оперативной памяти как диска не является примером распределенности, данный подход легко может быть приспособлен для увеличения производительности сайта. Запомните информация находящаяся на таком диске исчезает после перезагрузки сервера.
Создание RAM-диска

Я бы попытался избегать такого подхода, так как считаю, что риск в этом случае перевешивает выгоду, когда речь идет о большом количестве серверов. В таком случае лучшем выходом является использование memcached.

Надеюсь, что описанное выше было достаточно информативно. Здесь не описан весь потенциал кэширования, например использование кэширования в распределенных базах данных или использование Squid. В будущих статьях я опишу и это…

Читайте также: