Ранее мы рассмотрели некоторые распространенные механизмы кэширования, которые можно легко использовать для ускорения работы наших приложений. В этой части мы рассмотрим некоторые дополнительные программы, которые мы можем использовать с PHP для кэширования.
Memcached
Memcached — это хранилище значений ключей в памяти. Вы можете использовать его для хранения таких вещей, как строки, числовые значения, объекты и массивы.
Установка Memcached
Вы можете выполнить команду ниже, чтобы установить memcached в Ubuntu или другой ОС на основе Debian:
sudo apt-get install memcached
Чтобы он работал с PHP, вам также необходимо установить расширение PHP:
sudo apt-get install php5-memcached
Чтобы проверить, работает ли memcached, найдите ‘memcached’ в выводе, возвращаемом при вызове phpinfo()
со страницы. Вы должны увидеть что-то похожее на следующее:
Использование Memcached
Чтобы использовать memcached, сначала мы создаем новый экземпляр класса Memcached
. Затем мы указываем, к какому серверу мы хотим подключиться, вызывая метод addServer
. $memcached_host
— это IP-адрес или доменное имя сервера, а $memcached_port
— это порт, на котором работает сервер memcached. По умолчанию это 11211.
$mem = new Memcached(); $memcached_host = '127.0.0.1'; $memcached_port = 11211; $mem->addServer($memcached_host, $memcached_port);
Как только это будет сделано, вы можете использовать метод set
для кэширования определенной пары ключ-значение. Метод set
принимает уникальный ключ в качестве первого аргумента и данные, которые вы хотите кэшировать, в качестве второго, а третий — продолжительность времени жизни данных в секундах:
$id = 23; $my_data = array('name' => 'gon', 'occupation' => 'hunter'); $ttl = 60; $mem->set($id, $my_data, $ttl);
Если вы хотите получить данные обратно, вы можете использовать метод get
. Просто используйте уникальный ключ в качестве запроса:
$my_data = $mem->get(23); if($my_data){ return $my_data; }else{ //fetch data from database }
Для дальнейшей оптимизации memcached вы можете настроить его параметры. Вы можете сделать это, отредактировав файл конфигурации memcached: /etc/memcached.conf
.
Вот некоторые из вариантов, которые вы можете найти полезными. Просто раскомментируйте их или отредактируйте существующие значения:
-v
— если вы хотите показать больше информации во время работы memcached.
-vv
— если вы не можете найти то, что ищете в подробном режиме, вы можете увидеть еще больше информации, когда вы установите эту опцию. Очень полезно при отладке.
-m
— максимальный объем памяти, который может использовать memcached. По умолчанию установлено 64 МБ.
-M
— сообщает memcached для возврата ошибки, когда максимальный объем памяти уже исчерпан. По умолчанию эта опция не установлена. Вместо этого он автоматически удаляет элементы из кэша.
-c
— максимально допустимое количество одновременных подключений. По умолчанию это 1024.
Вы также можете установить phpMemcachedAdmin на свой memcached сервер. Он покажет вам такие вещи, как общее количество текущих подключений, ошибок подключения, текущие элементы, общий объем используемой памяти и другие данные, которые могут оказаться полезными. Вот скриншот:
лакировка
Varnish — это программа, которая работает перед веб-сервером и ускоряет работу веб-приложений. Это означает, что когда пользователь заходит на ваш сайт, Varnish получает первоначальный запрос вместо веб-сервера. Если запрашиваемый контент уже существует в кэше, Varnish получает его из кэша и обслуживает его. Если он не существует, он просит веб-сервер обслужить его, помещает ответ в кэш, а затем отправляет его пользователю. В следующий раз, когда запрашивается та же страница, она извлечет ее из кэша.
Установка лака
Чтобы установить Varnish, вы должны сначала добавить репозиторий в ваши источники:
sudo curl http://repo.varnish-cache.org/debian/GPG-key.txt | sudo apt-key add -
Затем выполните следующее, чтобы установить Varnish:
sudo apt-get update sudo apt-get install varnish
Конфигурирование лака
Далее вам нужно настроить Varnish на основе вашего веб-сервера. В этом уроке я предполагаю, что веб-сервером является Apache. Начните с открытия файла конфигурации Varnish в /etc/default/varnish
.
Ищите «DAEMON_OPTS», без комментариев. Убедитесь, что это так же, как показано ниже:
DAEMON_OPTS="-a :80 \ -T localhost:6082 \ -f /etc/varnish/default.vcl \ -S /etc/varnish/secret \ -s malloc,256m"
Вот разбивка опций, которые мы использовали выше:
-
-a
— это адрес и порт Varnish слушает. В конфигурации выше мы не указали адрес. Это означает, что Varnish будет прослушивать запросы на том же сервере, где установлен веб-сервер. Обычно вам нужно установить Varnish на другой сервер, чтобы он не подвергался такой же нагрузке, как веб-сервер. -
-T
— адрес и порт, который прослушивает интерфейс управления. -
-f
— позволяет указать собственный файл конфигурации VCL вместо файла по умолчанию. -
S
— путь к файлу, содержащему секрет, используемый для авторизации доступа к порту управления. -
-s
— используется для указания серверной части хранилища. Вы можете использовать любой из вариантов на этой странице . Обычно этоmalloc
, который использует память в качестве кеша. Это запрашивает максимальный объем памяти, который будет указан. В этом случае это256m
что составляет 256 МБ.
Далее нам нужно отредактировать файл конфигурации Varnish VCL ( /etc/varnish/default.vcl
). Это позволяет нам установить сервер, который будет служить источником.
В этом случае мы используем Apache на той же машине, где установлен Varnish, поэтому мы можем установить для хоста localhost
и для порта 8888
.
backend default { .host = "localhost"; .port = "8888"; }
По умолчанию Apache работает на порте 80. Ранее мы настраивали Varnish для прослушивания порта 80, поэтому нам нужно заменить Apache 80 на что-то другое, иначе возникнет конфликт между Apache и Varnish.
Мы обновляем конфигурацию Apache: /etc/apache2/sites-enabled/000-default.conf
.
Мы уверены, что виртуальный хост теперь настроен на порт 8888.
<VirtualHost 127.0.0.1:8888>
Затем мы также должны обновить файл конфигурации портов: /etc/apache2/ports.conf
Мы уверены, что у него есть определение виртуального хоста с использованием того же хоста и порта, которые используются в файле конфигурации Apache:
Listen 127.0.0.1:8888
Затем мы перезапускаем Apache, чтобы изменения вступили в силу.
sudo service apache2 restart
Используя Лак
После этого Varnish теперь готов кешировать. Давайте попробуем, создав новый файл PHP, который покажет нам некоторые новости из базы данных. Если вы хотите следовать, используйте этот github gist для получения данных. Ниже вы найдете файл PHP, который мы будем использовать для тестирования. Он выбирает title
и url
статьи из таблицы новостей и выводит их в виде таблицы:
<?php $db = new Mysqli(DB_HOST, DB_USER, DB_PASSWORD, DB_NAME); $results = $db->query("SELECT title, url FROM news"); ?> <table border="1"> <thead> <tr> <th>title</th> <th>url</th> </tr> </thead> <tbody> <?php while($row = $results->fetch_object()){ ?> <tr> <td><?php echo $row->title; ?></td> <td><?php echo $row->url; ?></td> </tr> <?php } ?> </tbody> </table>
Откройте панель сети в Chrome Dev Tools и проверьте общее время, необходимое для получения всей страницы. В моем тесте это заняло 192 мс:
Теперь обновите страницу и проверьте общее время, которое требуется снова. Это заняло у меня 90 мс:
Давайте также проверим заголовки ответа, которые мы получаем от второго запроса:
Здесь важно отметить Age
и заголовки X-Varnish
. При первоначальном запросе определенной страницы значение Age
имеет значение 0
, и оно будет увеличиваться при последующих запросах. Вы знаете, что Varnish работает, когда вы видите, что Age
увеличивается каждый раз, когда вы обновляете одну и ту же страницу. Заголовок X-Varnish
имеет одно значение при первом запросе страницы. Он будет иметь два значения, когда получит что-то из кэша. Первое значение — это идентификатор запроса — уникальный идентификатор, назначаемый лаком для этого конкретного запроса страницы. Второе значение — это идентификатор запроса, из которого был заполнен кэшированный ответ, который в основном является идентификатором запроса из начального запроса страницы.
Библиотеки
В этом разделе я сделаю краткий обзор некоторых библиотек PHP, которые вы можете использовать для кэширования.
Доктрина Кеш
Doctrine — это кеширующий компонент реляционного картографа объекта Doctrine. Это позволяет использовать разные драйверы для кэширования пользовательских данных. Драйверы включают APC, Memcache, Memcached, XCache и Redis.
Вы можете установить его, выполнив следующую команду из вашего терминала:
composer require doctrine/cache
Вот пример того, как кэшировать пользовательские данные на сервере memcached:
require 'vendor/autoload.php'; $memcached = new Memcached(); $port = 11211; $memcached->addServer($memcache_host, $port); $cacheDriver = new \Doctrine\Common\Cache\MemcachedCache(); $cacheDriver->setMemcached($memcached); $cacheDriver->save($cache_id, $my_data);
Сначала мы инициализируем memcached. Затем мы устанавливаем сервер memcached, вызывая метод setMemcached
и передавая ему экземпляр memcached, который мы объявили ранее. Наконец, мы кешируем данные, вызывая метод save
. Эта функция требует уникального идентификатора в качестве первого аргумента и данных в качестве второго аргумента.
Вы можете найти больше информации о том, как подключиться с помощью определенного драйвера в их официальной документации .
копить
Как и Doctrine Cache, Stash — это библиотека для кэширования PHP. Это позволяет нам кэшировать результаты от вызовов базы данных, дорогостоящих вычислений и данных, которые мы можем повторно использовать во всем приложении. Он также поддерживает разные драйверы:
- FileSystem — хранит элементы в файловой системе.
- Sqlite — сохраняет элементы в базе данных sqlite.
- APC — кеш на основе памяти, использующий PHP-расширение APC.
- Memcached — использует memcached сервер для хранения предметов.
- Redis — хранит элементы в системе хранения ключ / значение.
- Ephemeral — кеширует элемент на весь срок действия сценария.
- Композитный — позволяет использовать вышеуказанные драйверы в качестве одного кеша.
В этой статье я расскажу вам только об использовании Stash с Memcached, поскольку мы уже использовали его ранее.
Установка Stash
Вы можете установить Stash с помощью Composer:
composer require tedivm/stash
Пробовать тайник
Если вы следовали ранее в разделе Varnish и вставили данные SQL, вы можете подключиться к той же базе данных. Далее подключитесь к серверу Memcached. В отличие от Doctrine Cache, Stash предоставляет собственную оболочку для подключения к Memcached, поэтому мы будем использовать ее вместо класса, предоставляемого расширением Memcached PHP.
$driver = new Stash\Driver\Memcache(); $driver->setOptions(array('servers' => array(MEMCACHED_HOST, MEMCACHED_PORT)));
Теперь мы можем объявить новый пул для использования драйвера memcached. Пул представляет собой систему кеширования. Мы используем его для добавления или извлечения элементов из кэша. Каждый элемент представлен уникальным ключом, и значением может быть любой тип данных, поддерживаемый в PHP. Это включает в себя целые числа, логические значения, строки, массивы и объекты. Из этого пула мы используем метод getItem
для извлечения определенного элемента.
Затем мы проверяем, существует ли элемент, который мы isMiss()
в кэше, используя метод isMiss()
. Если этот метод возвращает true
то элемент еще не существует в кэше, и нам нужно извлечь его из исходного источника. В этом случае база данных. Мы перебираем полученные результаты и сохраняем их в массиве.
Как только мы перебрали все элементы, мы вызываем метод lock()
в пуле. Это сообщает другим процессам, что текущий процесс генерирует новый набор данных. Затем мы вызываем метод set()
для назначения данных, которые мы извлекли из базы данных, в пул. Как только это будет сделано, мы вызываем метод get()
чтобы мы могли извлечь данные, которые мы кэшировали.
$pool = new Stash\Pool($driver); $item = $pool->getItem('news'); if($item->isMiss()){ $results = $db->query("SELECT title, url FROM news"); while($row = $results->fetch_object()){ $data[] = array( 'title' => $row->title, 'url' => $row->url ); } $item->lock(); $item->set($data); } $news_items = $item->get(); ?> <table border="1"> <thead> <tr> <th>title</th> <th>url</th> </tr> </thead> <tbody> <?php foreach($news_items as $row){ ?> <tr> <td><?php echo $row['title']; ?></td> <td><?php echo $row['url']; ?></td> </tr> <?php } ?> </tbody> </table>
Вывод
В этой статье мы рассмотрели еще несколько техник, программного обеспечения и библиотек, которые мы можем использовать для повышения производительности приложений и веб-сайтов, которые мы разрабатываем с использованием PHP. Какие подходы кеширования вы используете? Дайте нам знать!