Улучшение производительности с кэшированием
Phalcon предоставляет класс Phalcon\Cache, позволяющий быстрее получать доступ к часто используемым или уже обработанным данным. Phalcon\Cache написан на C, что обеспечивает более высокую производительность и снижает нагрузку при получении элементов из кэша. Этот класс использует внутреннюю структуру с компонентами frontend и backend. Компоненты frontend выступают в роли источников или интерфейсов ввода, в то время как компоненты backend предлагают варианты хранения для класса.
Когда следует использовать кэширование?
Хотя этот компонент очень быстрый, его внедрение в случаях, когда оно не нужно, может привести к снижению, а не повышению производительности. Мы рекомендуем проверить эти случаи перед использованием кэша:
- Вы выполняете сложные вычисления, которые каждый раз возвращают один и тот же результат (редко меняющийся)
- Вы используете много вспомогательных функций, и генерируемый вывод почти всегда одинаков
- Вы постоянно получаете доступ к данным базы данных, и эти данные редко изменяются
ПРИМЕЧАНИЕ Даже после внедрения кэша следует отслеживать коэффициент попаданий в кэш в течение определенного периода времени. Это можно легко сделать, особенно в случае Memcache или Apc, с помощью соответствующих инструментов, которые предоставляют backend'ы.
Поведение кэширования
Процесс кэширования разделен на 2 части:
- Frontend: Эта часть отвечает за проверку истечения срока действия ключа и выполнение дополнительных преобразований данных перед сохранением и после получения их из backend.
- Backend: Эта часть отвечает за взаимодействие, запись/чтение данных, необходимых frontend.
Кэширование фрагментов вывода
Фрагмент вывода — это фрагмент HTML или текста, который кэшируется как есть и возвращается как есть. Вывод автоматически собирается из функций ob_* или вывода PHP, чтобы он мог быть сохранен в кэше. Следующий пример демонстрирует такое использование. Он получает вывод, сгенерированный PHP, и сохраняет его в файл. Содержимое файла обновляется каждые 172800 секунд (2 дня).
Реализация этого механизма кэширования позволяет повысить производительность, не выполняя вызов вспомогательной функции Phalcon\Tag::linkTo(), когда этот фрагмент кода вызывается.
use Phalcon\Tag;
use Phalcon\Cache\Backend\File as BackFile;
use Phalcon\Cache\Frontend\Output as FrontOutput;
// Create an Output frontend. Cache the files for 2 days
$frontCache = new FrontOutput(
[
"lifetime" => 172800,
]
);
// Create the component that will cache from the "Output" to a "File" backend
// Set the cache file directory - it's important to keep the "/" at the end of
// the value for the folder
$cache = new BackFile(
$frontCache,
[
"cacheDir" => "../app/cache/",
]
);
// Get/Set the cache file to ../app/cache/my-cache.html
$content = $cache->start("my-cache.html");
// If $content is null then the content will be generated for the cache
if ($content === null) {
// Print date and time
echo date("r");
// Generate a link to the sign-up action
echo Tag::linkTo(
[
"user/signup",
"Sign Up",
"class" => "signup-button",
]
);
// Store the output into the cache file
$cache->save();
} else {
// Echo the cached output
echo $content;
}
ПРИМЕЧАНИЕ В примере выше наш код остается прежним, выводя на экран информацию пользователю, как и раньше. Наш компонент кэширования прозрачно собирает этот вывод и сохраняет его в файле кэша (при создании кэша) или возвращает его пользователю предварительно скомпилированным из предыдущего вызова, тем самым избегая дорогостоящих операций.
Кэширование произвольных данных
Кэширование данных также имеет важное значение для вашей приложения. Кэширование может уменьшить нагрузку на базу данных, повторно используя часто используемые (но не обновляемые) данные, тем самым ускоряя работу вашей приложения.
Пример File Backend
Один из адаптеров кэширования — ‘File’. Единственная важная область для этого адаптера — местоположение, где будут храниться файлы кэша. Это контролируется параметром cacheDir, который должен заканчиваться обратной косой чертой.
use Phalcon\Cache\Backend\File as BackFile;
use Phalcon\Cache\Frontend\Data as FrontData;
// Cache the files for 2 days using a Data frontend
$frontCache = new FrontData(
[
"lifetime" => 172800,
]
);
// Create the component that will cache "Data" to a "File" backend
// Set the cache file directory - important to keep the "/" at the end of
// the value for the folder
$cache = new BackFile(
$frontCache,
[
"cacheDir" => "../app/cache/",
]
);
$cacheKey = "robots_order_id.cache";
// Try to get cached records
$robots = $cache->get($cacheKey);
if ($robots === null) {
// $robots is null because of cache expiration or data does not exist
// Make the database call and populate the variable
$robots = Robots::find(
[
"order" => "id",
]
);
// Store it in the cache
$cache->save($cacheKey, $robots);
}
// Use $robots :)
foreach ($robots as $robot) {
echo $robot->name, "\n";
}
Пример Memcached Backend
Вышеприведенный пример незначительно изменяется (особенно в плане конфигурации), когда мы используем backend Memcached.
use Phalcon\Cache\Frontend\Data as FrontData;
use Phalcon\Cache\Backend\Libmemcached as BackMemCached;
// Cache data for one hour
$frontCache = new FrontData(
[
"lifetime" => 3600,
]
);
// Create the component that will cache "Data" to a "Memcached" backend
// Memcached connection settings
$cache = new BackMemCached(
$frontCache,
[
"servers" => [
[
"host" => "127.0.0.1",
"port" => "11211",
"weight" => "1",
]
]
]
);
$cacheKey = "robots_order_id.cache";
// Try to get cached records
$robots = $cache->get($cacheKey);
if ($robots === null) {
// $robots is null because of cache expiration or data does not exist
// Make the database call and populate the variable
$robots = Robots::find(
[
"order" => "id",
]
);
// Store it in the cache
$cache->save($cacheKey, $robots);
}
// Use $robots :)
foreach ($robots as $robot) {
echo $robot->name, "\n";
}
Запрос кэша
Элементы, добавленные в кэш, уникально идентифицируются ключом. В случае File backend, ключ — это фактическое имя файла. Чтобы получить данные из кэша, достаточно вызвать его с помощью уникального ключа. Если ключ не существует, метод get вернёт null.
// Retrieve products by key "myProducts"
$products = $cache->get("myProducts");
Если вы хотите узнать, какие ключи хранятся в кэше, вы можете вызвать метод queryKeys:
// Query all keys used in the cache
$keys = $cache->queryKeys();
foreach ($keys as $key) {
$data = $cache->get($key);
echo "Key=", $key, " Data=", $data;
}
// Query keys in the cache that begins with "my-prefix"
$keys = $cache->queryKeys("my-prefix");
Удаление данных из кэша
Иногда вам нужно принудительно аннулировать запись кэша (из-за обновления кэшированных данных). Единственное требование — знать ключ, с которым данные были сохранены.
// Delete an item with a specific key
$cache->delete("someKey");
$keys = $cache->queryKeys();
// Delete all items from the cache
foreach ($keys as $key) {
$cache->delete($key);
}
Проверка существования кэша
Можно проверить, существует ли кэш с заданным ключом:
if ($cache->exists("someKey")) {
echo $cache->get("someKey");
} else {
echo "Cache does not exists!";
}
Срок действия
Срок действия — это время в секундах, в течение которого кэш может существовать без истечения срока действия. По умолчанию все созданные кэши используют срок действия, установленный при создании frontend. Вы можете установить определенный срок действия при создании или получении данных из кэша:
Установка срока действия при получении:
$cacheKey = "my.cache";
// Setting the cache when getting a result
$robots = $cache->get($cacheKey, 3600);
if ($robots === null) {
$robots = "some robots";
// Store it in the cache
$cache->save($cacheKey, $robots);
}
Установка срока действия при сохранении:
$cacheKey = "my.cache";
$robots = $cache->get($cacheKey);
if ($robots === null) {
$robots = "some robots";
// Setting the cache when saving data
$cache->save($cacheKey, $robots, 3600);
}
Многоуровневый кэш
Эта функция компонента кэширования позволяет разработчику реализовать многоуровневый кэш. Эта новая функция очень полезна, поскольку позволяет сохранить одни и те же данные в нескольких местах кэша с разными сроками действия, сначала читая из самого быстрого адаптера и заканчивая самым медленным до истечения срока действия данных:
use Phalcon\Cache\Multiple;
use Phalcon\Cache\Backend\Apc as ApcCache;
use Phalcon\Cache\Backend\File as FileCache;
use Phalcon\Cache\Frontend\Data as DataFrontend;
use Phalcon\Cache\Backend\Memcache as MemcacheCache;
$ultraFastFrontend = new DataFrontend(
[
"lifetime" => 3600,
]
);
$fastFrontend = new DataFrontend(
[
"lifetime" => 86400,
]
);
$slowFrontend = new DataFrontend(
[
"lifetime" => 604800,
]
);
// Backends are registered from the fastest to the slower
$cache = new Multiple(
[
new ApcCache(
$ultraFastFrontend,
[
"prefix" => "cache",
]
),
new MemcacheCache(
$fastFrontend,
[
"prefix" => "cache",
"host" => "localhost",
"port" => "11211",
]
),
new FileCache(
$slowFrontend,
[
"prefix" => "cache",
"cacheDir" => "../app/cache/",
]
),
]
);
// Save, saves in every backend
$cache->save("my-key", $data);
Адаптеры Frontend
Доступные адаптеры frontend, которые используются в качестве интерфейсов или источников ввода для кэша:
| Адаптер | Описание |
|---|---|
| Phalcon\Cache\Frontend\Output | Чтение входных данных из стандартного вывода PHP |
| Phalcon\Cache\Frontend\Data | Используется для кэширования любых данных PHP (больших массивов, объектов, текста и т. д.). Данные сериализуются перед хранением в backend. |
| Phalcon\Cache\Frontend\Base64 | Используется для кэширования двоичных данных. Данные сериализуются с помощью base64_encode перед хранением в backend. |
| Phalcon\Cache\Frontend\Json | Данные кодируются в формате JSON перед хранением в backend. Декодируются после извлечения. Этот frontend полезен для обмена данными с другими языками или фреймворками. |
| Phalcon\Cache\Frontend\Igbinary | Используется для кэширования любых данных PHP (больших массивов, объектов, текста и т. д.). Данные сериализуются с помощью IgBinary перед хранением в backend. |
| Phalcon\Cache\Frontend\None | Используется для кэширования любых данных PHP без сериализации. |
Реализация собственных адаптеров Frontend
Для создания собственных адаптеров frontend или расширения существующих адаптеров необходимо реализовать интерфейс Phalcon\Cache\FrontendInterface.
Адаптеры Backend
Доступные адаптеры backend для хранения кэшированных данных:
| Адаптер | Описание | Информация | Необходимые расширения |
|---|---|---|---|
| Phalcon\Cache\Backend\File | Хранит данные в локальных текстовых файлах | ||
| Phalcon\Cache\Backend\Memcache | Хранит данные на сервере memcached | Memcached | memcache |
| Phalcon\Cache\Backend\Apc | Хранит данные в кэше Alternative PHP (APC) | APC | Расширение APC |
| Phalcon\Cache\Backend\Mongo | Хранит данные в базе данных Mongo | MongoDb | Mongo |
| Phalcon\Cache\Backend\Xcache | Хранит данные в XCache | XCache | расширение xcache |
| Phalcon\Cache\Backend\Redis | Хранит данные в Redis | Redis | расширение redis |
Реализация собственных адаптеров Backend
Для создания собственных адаптеров backend или расширения существующих адаптеров необходимо реализовать интерфейс Phalcon\Cache\BackendInterface.
Параметры File Backend
Этот backend будет хранить кэшируемое содержимое в файлах на локальном сервере. Доступные параметры для этого backend:
| Параметр | Описание |
|---|---|
| prefix | Префикс, который автоматически добавляется к ключам кэша |
| cacheDir | Папка, в которую будут помещаться кэшированные файлы (должна быть доступна для записи) |
Параметры Memcached Backend
Этот backend будет хранить кэшируемое содержимое на сервере memcached. Доступные параметры для этого backend:
| Параметр | Описание |
|---|---|
| prefix | Префикс, который автоматически добавляется к ключам кэша |
| host | Хост memcached |
| port | Порт memcached |
| persistent | Создать постоянное соединение с memcached? |
Параметры бэкенда APC
Этот бэкенд будет хранить кэшируемый контент в кэше Alternative PHP Cache (APC). Доступные параметры для этого бэкенда:
| Параметр | Описание |
|---|---|
| prefix | Префикс, который автоматически добавляется к ключам кэша |
Параметры бэкенда Mongo
Этот бэкенд будет хранить кэшируемый контент на сервере MongoDB. Доступные параметры для этого бэкенда:
| Параметр | Описание |
|---|---|
| prefix | Префикс, который автоматически добавляется к ключам кэша |
| server | Строка подключения к MongoDB |
| db | Имя базы данных MongoDB |
| collection | Имя коллекции в базе данных |
Параметры бэкенда XCache
Этот бэкенд будет хранить кэшируемый контент в XCache (XCache). Доступные параметры для этого бэкенда:
| Параметр | Описание |
|---|---|
| prefix | Префикс, который автоматически добавляется к ключам кэша |
Параметры бэкенда Redis
Этот бэкенд будет хранить кэшируемый контент на сервере Redis (Redis). Доступные параметры для этого бэкенда:
| Параметр | Описание |
|---|---|
| prefix | Префикс, который автоматически добавляется к ключам кэша |
| host | Хост Redis |
| port | Порт Redis |
| auth | Пароль для аутентификации на защищённом паролем сервере Redis |
| persistent | Создать постоянное подключение к Redis |
| index | Индекс базы данных Redis для использования |
В Phalcon Incubator доступно больше адаптеров для этой компоненты.
© 2011–2017 Phalcon Framework Team
Licensed under the Creative Commons Attribution License 3.0.
https://docs.phalconphp.com/en/latest/reference/cache.html