Пулы кеша и поддерживаемые адаптеры
Дата обновления перевода 2024-06-14
Пулы кеша и поддерживаемые адаптеры
Пулы кеша это логичные хранилища кешированных объектов. Они проводят все общие операции на объектах, вроде их сохранения или поиска. Пулы кешей не зависят от самой реализации кеша. Следовательно, приложения могут продолжать использовать один и тот же пул кеша, даже если основопоожный механизм кеша меняется из кеша, основанного на файловой системе, на кеш, основанный на Redis или DB.
Создание пулов кеша
Пулы кеша создаются через адаптеры кеша, которые являются классами,
реализующими как AdapterInterface,
так и Psr\Cache\CacheItemPoolInterface
. Этот компонент предоставляет несколько
адаптеров, готовых к использованию в ваших приложениях.
- Адаптер кеша APCu
- Адаптер массива кеша
- Адаптер цепочки кеша
- Адаптер кеша Couchbase Bucket
- Адаптер коллекции кеша Couchbase
- Адаптер кеша Doctrine
- Адаптер кеша Doctrine DBAL
- Адаптер кеша Filesystem
- Адаптер кеша Memcached
- Адаптер кеша PDO
- Адаптер кеша PDO & Doctrine DBAL
- Адаптер кеша PHP массива
- Адаптер кеша PHP-файлов
- Адаптер кеша прокси
- Адаптер кеша Redis
Использование контрактов кеша
CacheInterface позволяет извлечение, сохранение и удаление объектов кеша, используя только два метода и обратный вызов:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Contracts\Cache\ItemInterface;
$cache = new FilesystemAdapter();
// Вызываемое будет выполнено только при промахе кеша.
$value = $cache->get('my_cache_key', function (ItemInterface $item): string {
$item->expiresAfter(3600);
// ... сделать какой-то HTTP-запрос или сложные исчисления
$computedValue = 'foobar';
return $computedValue;
});
echo $value; // 'foobar'
// ... и чтобы удалить ключ кеша
$cache->delete('my_cache_key');
Сразу после установки использование этого интерфейса обеспечивает защиту через блокирования и досрочное истечение срока действия. Досрочное истечение срока действия можно контролировать с помощью третьего аргумента "beta" метода get(). Более подробную информацию см. в статье Компонент Cache.
Досрочное истечение срока действия может быть обнаружено внутри обратного вызова путем
вызова метода isHit(): если этот метод
возвращает true
, то это означает, что мы в данный момент перевычисляем значение раньше,
чем истекает срок его действия.
Для более сложных случаев обратный вызов может принимать второй аргумент bool &$save
,
передаваемый по ссылке. Установив внутри обратного вызова $save
в значение false
,
можно указать пулу кеша, что возвратное значение не должно храниться в бэкенде.
Использование PSR-6
Поиск объектов кеша
Пулы кеша определяют три метода поиска объектов кеша. Наиболее распространённым
методом является getItem($key)
, который возвращает идентификатор объекта кеша
по заданному ключу:
1 2 3 4
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter('app.cache');
$latestNews = $cache->getItem('latest_news');
Если для заданного ключа не определено ни одного объекта, метод не возвращает
значение null
, а возвращает пустой объект, реализующий класс
CacheItem.
Если вам нужно извлечь несколько объектов кеша одновременно, то лучше
используйте метод getItems(array($key1, $key2, ...))
:
1 2
// ...
$stocks = $cache->getItems(array('AAPL', 'FB', 'GOOGL', 'MSFT'));
Опять же, если ни один из ключей не представляет валидный объект кеша, вы не
получите значение null
,а получите пустой объект CacheItem
.
Последний метод, связанный с извлечением объектов кеша, является hasItem($key)
,
который возвращает true
, если существует объект кеша, идентифицироанный
заданным ключом:
1 2
// ...
$hasBadges = $cache->hasItem('user_'.$userId.'_badges');
Сохранение объектов кеша
Наиболее распространённым методом для сохранения объектов кеша является
Psr
, который сохраняет объект в кеше
незамедлительно (возвращает true
, если объект был сохранён, или false
,
если произошла какая-то ошибка):
1 2 3 4
// ...
$userFriends = $cache->getItem('user_'.$userId.'_friends');
$userFriends->set($user->getFriends());
$isSaved = $cache->save($userFriends);
Иногда вам может захотеться не сохранять объекты немедленно, чтобы повысить
производительность вашего приложения. В таких случаях, используйте метод
Psr
, чтобы отметить объекты
кеша, как "готовые к сохранению" и потом вызовите метод
Psr
, когда вы будете готовы сохранить
их все:
1 2 3 4 5 6 7 8
// ...
$isQueued = $cache->saveDeferred($userFriends);
// ...
$isQueued = $cache->saveDeferred($userPreferences);
// ...
$isQueued = $cache->saveDeferred($userRecentProducts);
// ...
$isSaved = $cache->commit();
Метод saveDeferred()
возвращает true
, когда объект кеша был успешно добавлен
в "очередь сохранения", и false
в других случаях. Метод commit()
возвращает
true
, когда все ожидающие объекты были успешно сохранены, и false
в других
случаях.
Удаление объектов кеша
Пулы кеша включают методы для удаления объекта кеша, некоторых из них, или всех.
Наиболее распространённым является Psr
,
который удаляет объект кеша, определяемый заданным ключом (возвращает true
,
когда объект был успешно удалён или не существует, и false
в других случаях):
1 2
// ...
$isDeleted = $cache->deleteItem('user_'.$userId);
Используйте метод Psr
, чтобы
удалять несколько объектов кеша одновременно (возвращает true
только, если
все объекты были удалены, даже если один или несколько из них не существуют):
1 2
// ...
$areDeleted = $cache->deleteItems(array('category1', 'category2'));
Наконец, чтобы удалить все объекты кеша, хранящиеся в пуле, используйте метод
Psr
(который возвращает true
,
когда все объекты были успешно удалены):
1 2
// ...
$cacheIsEmpty = $cache->clear();
Tip
Если компонент кеша используется внутри приложения Symfony, вы можете удалить объекты из пулов кеша, используя следующий команды (которые находятся в рамках пакета framework):
Для того, чтобы удалить один конкретный объект из заданного пула:
1 2 3 4
$ php bin/console cache:pool:delete <cache-pool-name> <cache-key-name>
# deletes the "cache_key" item from the "cache.app" pool
$ php bin/console cache:pool:delete cache.app cache_key
Вы также можете удалить все объекты из заданного пула(ов):
1 2 3 4 5 6 7
$ php bin/console cache:pool:clear <cache-pool-name>
# очищает пул "cache.app"
$ php bin/console cache:pool:clear cache.app
# очищает пул "cache.validation" и "cache.app"
$ php bin/console cache:pool:clear cache.validation cache.app
Отсечение объектов кеша
Некоторые пулы кеша не включают в себя автоматизированный механизм для отсечения просроченных
объектов кеша. Например, кеш FilesystemAdapter не
удаляет просроченные объекты кеша пока объект не будет ясно запрошен и определён, как испорченный,
например, через вызов к Psr
. При определённой
нагрузке, это может привести к сохранению устарелых записей кеша после срока истечения их
действия, что, в свою очередь, приведёт к ощутимому потреблению зря потраченного пространства
на диске или памяти в связи с излишними просроченными объектами кеша.
Этот недостаток был решён путём введения PruneableInterface, который определяет абстрактный метод prune(). ChainAdapter, DoctrineDbalAdapter и FilesystemAdapter, PdoAdapter и PhpFilesAdapter - все реализуют этот новый интерфейс, позволяя ручное удаление устаревших объектов кеша:
1 2 3 4 5
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter('app.cache');
// ... провести какие-то операции set и get
$cache->prune();
Релизация ChainAdapter не содержит напрямую какой-либо
логики усечения. Вместо этого, при вызове метода цепи адаптеров
prune(), вызов делегируется всем
совместимым с ним адаптерам кеша (а те, которые не реализуют PruneableInterface
,
тихо игнорируются):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
use Symfony\Component\Cache\Adapter\ApcuAdapter;
use Symfony\Component\Cache\Adapter\ChainAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\PdoAdapter;
use Symfony\Component\Cache\Adapter\PhpFilesAdapter;
$cache = new ChainAdapter([
new ApcuAdapter(), // НЕ реализует PruneableInterface
new FilesystemAdapter(), // РЕАЛИЗУЕТ PruneableInterface
new PdoAdapter(), // РЕАЛИЗУЕТ PruneableInterface
new PhpFilesAdapter(), // РЕАЛИЗУЕТ PruneableInterface
// ...
]);
// prune проксирует вызов к PdoAdapter, FilesystemAdapter и PhpFilesAdapter,
// тихо пропуская ApcuAdapter
$cache->prune();
Tip
Если компонент кеша использовуется внутри приложения Symfony, то вы можете отсечь все объекты из всех пулов, используя следующую команду (которая находится в пакете framework):
1
$ php bin/console cache:pool:prune