Spec-Zone.ru › Phalcon 3

Улучшение производительности с кэшированием

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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API