From ea292523155f720611e952c82eb93e690fec522c Mon Sep 17 00:00:00 2001 From: Rob Frawley 2nd Date: Fri, 21 Jul 2017 22:58:16 -0400 Subject: [PATCH 1/5] document cache pruning functionality - note the addition of PruneableInterface - note the variouse, concrete PruneableInterface::prune() implementations in ChainAdapter, FilesystemAdapter, PdoAdapter, PhpFilesAdapter, ChainCache, FilesystemCache, PdoCache, PhpFilesCache, and TagAwareAdapter. - note the addition of CachePoolPruneCommand, invokable via cache:pool:prune. This command iterates over all services tagged cache.pool and calls the PruneableInterface::prune() method on those that implement PruneableInterface - rewording of some adapter text for clarity - additional note blocks for all caches that implement PruneableInterface - addition of prune() description and usage example on the chain adapter - addition of a tip about achieving better performance with the filesystem adapter by utilizing tmpfs or another ram disk solution - fix for an incorrect use statement in the PHP array cache adapter code example - addition of documentation page for PHP files adapter - addition of a "pruning cache items" explanation and example on the main cache pools page --- components/cache/adapters/apcu_adapter.rst | 24 +++--- components/cache/adapters/chain_adapter.rst | 38 ++++++++-- .../cache/adapters/filesystem_adapter.rst | 38 +++++++--- .../adapters/pdo_doctrine_dbal_adapter.rst | 6 ++ .../adapters/php_array_cache_adapter.rst | 2 +- .../cache/adapters/php_files_adapter.rst | 63 ++++++++++++++++ components/cache/cache_invalidation.rst | 10 +++ components/cache/cache_pools.rst | 73 ++++++++++++++++++- reference/configuration/framework.rst | 2 + 9 files changed, 222 insertions(+), 34 deletions(-) create mode 100644 components/cache/adapters/php_files_adapter.rst diff --git a/components/cache/adapters/apcu_adapter.rst b/components/cache/adapters/apcu_adapter.rst index e064b6c9814..0b5c9b30bdf 100644 --- a/components/cache/adapters/apcu_adapter.rst +++ b/components/cache/adapters/apcu_adapter.rst @@ -7,19 +7,17 @@ APCu Cache Adapter ================== -This adapter is a high-performance, shared memory cache. It can increase the -application performance very significantly because the cache contents are -stored in the shared memory of your server, a component that is much faster than -others, such as the filesystem. +This adapter is a high-performance, shared memory cache. It can *significantly* increase +an application's performance, as its cache contents are stored in shared memory, a component +appreciably faster than many others, such as the filesystem. .. caution:: **Requirement:** The `APCu extension`_ must be installed and active to use this adapter. -This adapter can be provided an optional namespace string as its first parameter, a -default cache lifetime as its second parameter, and a version string as its third -parameter:: +The ApcuAdapter can optionally be provided a namespace, default cache lifetime, and cache +items version string as constructor arguments:: use Symfony\Component\Cache\Adapter\ApcuAdapter; @@ -40,15 +38,13 @@ parameter:: .. caution:: - It is *not* recommended to use this adapter when performing a large number of - write and delete operations, as these operations result in fragmentation of the - APCu memory, resulting in *significantly* degraded performance. + Use of this adapter is discouraged in write/delete heavy workloads, as these + operations cause memory fragmentation that results in significantly degraded performance. .. tip:: - Note that this adapter's CRUD operations are specific to the PHP SAPI it is running - under. This means adding a cache item using the CLI will not result in the item - appearing under FPM. Likewise, deletion of an item using CGI will not result in the - item being deleted under the CLI. + This adapter's CRUD operations are specific to the PHP SAPI it is running under. This + means cache operations (such as additions, deletions, etc) using the CLI will not be + available under the FPM or CGI SAPIs. .. _`APCu extension`: https://pecl.php.net/package/APCu \ No newline at end of file diff --git a/components/cache/adapters/chain_adapter.rst b/components/cache/adapters/chain_adapter.rst index f3d5cfc0253..a91ab859edc 100644 --- a/components/cache/adapters/chain_adapter.rst +++ b/components/cache/adapters/chain_adapter.rst @@ -2,15 +2,18 @@ single: Cache Pool single: Chain Cache +.. _component-cache-chain-adapter: + Chain Cache Adapter =================== -This adapter allows to combine any number of the other available cache adapters. -Cache items are fetched from the first adapter which contains them and cache items are -saved in all the given adapters. This offers a simple way of creating a layered cache. +This adapter allows combining any number of the other +:ref:`available cache adapters `. Cache items are +fetched from the first adapter containing them and cache items are saved to all the +given adapters. This exposes a simple and efficient method for creating a layeted cache. -This adapter expects an array of adapters as its first parameter, and optionally a -maximum cache lifetime as its second parameter:: +The ChainAdapter must be provided an array of adapters and optionally a maximum cache +lifetime as its constructor arguments:: use Symfony\Component\Cache\Adapter\ApcuAdapter; @@ -26,7 +29,7 @@ maximum cache lifetime as its second parameter:: .. note:: When an item is not found in the first adapter but is found in the next ones, this - adapter ensures that the fetched item is saved in all the adapters where it was + adapter ensures that the fetched item is saved to all the adapters where it was previously missing. The following example shows how to create a chain adapter instance using the fastest and @@ -41,3 +44,26 @@ slowest storage engines, :class:`Symfony\\Component\\Cache\\Adapter\\ApcuAdapter new ApcuAdapter(), new FilesystemAdapter(), )); + +When calling this adapter's :method:`Symfony\\Component\\Cache\\ChainAdapter::prune` method, +the call is deligated to all its compatibe cache adapters. It is safe to mix both adapters +that *do* and do *not* implement :class:`Symfony\\Component\\Cache\\PruneableInterface`, as +incompatible adapters are silently ignored:: + + use Symfony\Component\Cache\Adapter\ApcuAdapter; + use Symfony\Component\Cache\Adapter\ChainAdapter; + use Symfony\Component\Cache\Adapter\FilesystemAdapter; + + $cache = new ChainAdapter(array( + new ApcuAdapter(), // does NOT implement PruneableInterface + new FilesystemAdapter(), // DOES implement PruneableInterface + )); + + // prune will proxy the call to FilesystemAdapter while silently skipping ApcuAdapter + $cache->prune(); + +.. note:: + + Since Symfony 3.4, this adapter implements :class:`Symfony\\Component\\Cache\\PruneableInterface`, + allowing for manual :ref:`pruning of expired cache entries ` by + calling its ``prune()`` method. diff --git a/components/cache/adapters/filesystem_adapter.rst b/components/cache/adapters/filesystem_adapter.rst index 5c8177199aa..f7aa7e495d5 100644 --- a/components/cache/adapters/filesystem_adapter.rst +++ b/components/cache/adapters/filesystem_adapter.rst @@ -2,15 +2,24 @@ single: Cache Pool single: Filesystem Cache +.. _component-cache-filesystem-adapter: + Filesystem Cache Adapter ======================== -This adapter is useful when you want to improve the application performance but -can't install tools like APCu or Redis on the server. This adapter stores the -contents as regular files in a set of directories on the local file system. +This adapter offers improved application performance for those who cannot install +tools like :ref:`APCu ` or :ref:`Redis ` in their +environment. It stores the cache item expiration and content as regular files in +a collection of directories on a locally mounted filesystem. + +.. tip:: + + The performance of this adapter can be greatly increased by utalizing a + temporary, in-memory filesystem, such as `tmpfs`_ on Linux, or one of the + many other `RAM disk solutions`_ available. -This adapter can optionally be provided a namespace, default cache lifetime, and -directory path, as its first, second, and third parameters:: +The FilesystemAdapter can optionally be provided a namespace, default cache lifetime, +and cache root path as constructor parameters:: use Symfony\Component\Cache\Adapter\FilesystemAdapter; @@ -30,9 +39,18 @@ directory path, as its first, second, and third parameters:: $directory = null ); -.. tip:: +.. caution:: + + The overhead of filesystem IO often makes this adapter one of the *slower* choices. If throughput is + paramount, the in-memory adapters (:ref:`Apcu `, :ref:`Memcached `, + and :ref:`Redis `) or the database adapters (:ref:`Doctrine ` and + :ref:`PDO `) are recommended. + +.. note:: + + Since Symfony 3.4, this adapter implements :class:`Symfony\\Component\\Cache\\PruneableInterface`, + enabling manual :ref:`pruning of expired cache items ` by + calling its ``prune()`` method. - This adapter is generally the *slowest* due to the overhead of file IO. If throughput is paramount, - the in-memory adapters (such as :ref:`APCu `, :ref:`Memcached `, - and :ref:`Redis `) or the database adapters (such as - :ref:`Doctrine ` and :ref:`PDO & Doctrine `) are recommended. +.. _`tmpfs`: https://wiki.archlinux.org/index.php/tmpfs +.. _`RAM disk solutions`: https://en.wikipedia.org/wiki/List_of_RAM_drive_software \ No newline at end of file diff --git a/components/cache/adapters/pdo_doctrine_dbal_adapter.rst b/components/cache/adapters/pdo_doctrine_dbal_adapter.rst index f826c20d604..bea7695d9c3 100644 --- a/components/cache/adapters/pdo_doctrine_dbal_adapter.rst +++ b/components/cache/adapters/pdo_doctrine_dbal_adapter.rst @@ -40,6 +40,12 @@ third, and forth parameters:: When passed a `Data Source Name (DSN)`_ string (instead of a database connection class instance), the connection will be lazy-loaded when needed. +.. note:: + + Since Symfony 3.4, this adapter implements :class:`Symfony\\Component\\Cache\\PruneableInterface`, + allowing for manual :ref:`pruning of expired cache entries ` by + calling its ``prune()`` method. + .. _`PDO`: http://php.net/manual/en/class.pdo.php .. _`Doctrine DBAL Connection`: https://github.com/doctrine/dbal/blob/master/lib/Doctrine/DBAL/Connection.php .. _`Data Source Name (DSN)`: https://en.wikipedia.org/wiki/Data_source_name diff --git a/components/cache/adapters/php_array_cache_adapter.rst b/components/cache/adapters/php_array_cache_adapter.rst index 2a45c3cf759..c2c722eae3f 100644 --- a/components/cache/adapters/php_array_cache_adapter.rst +++ b/components/cache/adapters/php_array_cache_adapter.rst @@ -9,7 +9,7 @@ This adapter is a highly performant way to cache static data (e.g. application c that is optimized and preloaded into OPcache memory storage:: use Symfony\Component\Cache\Adapter\PhpArrayAdapter; - use Symfony\Component\Cache\Adapter\PhpFilesAdapter; + use Symfony\Component\Cache\Adapter\FilesystemAdapter; // somehow, decide it's time to warm up the cache! if ($needsWarmup) { diff --git a/components/cache/adapters/php_files_adapter.rst b/components/cache/adapters/php_files_adapter.rst new file mode 100644 index 00000000000..158bc6efc09 --- /dev/null +++ b/components/cache/adapters/php_files_adapter.rst @@ -0,0 +1,63 @@ +.. index:: + single: Cache Pool + single: PHP Files Cache + +.. _component-cache-files-adapter: + +Php Files Cache Adapter +======================= + +Similarly to :ref:`Filesystem Adapter `, this cache +implementation writes cache entries out to disk, but unlike the Filesystem cache adapter, +the PHP Files cache adapter writes and reads back these cache files *as native PHP code*. +For example, caching the value ``array('my', 'cached', 'array')`` will write out a cache +file similar to the following:: + + 9223372036854775807, + + // the cache item contents + 1 => array ( + 0 => 'my', + 1 => 'cached', + 2 => 'array', + ), + + ); + +.. note:: + + As cache items are included and parsed as native PHP code and due to the way `OPcache`_ + handles file includes, this adapter has the potential to be much faster than other + filesystem-based caches. + +The PhpFilesAdapter can optionally be provided a namespace, default cache lifetime, and cache +directory path as constructor arguments:: + + use Symfony\Component\Cache\Adapter\PhpFilesAdapter; + + $cache = new PhpFilesAdapter( + + // a string used as the subdirectory of the root cache directory, where cache + // items will be stored + $namespace = '', + + // the default lifetime (in seconds) for cache items that do not define their + // own lifetime, with a value 0 causing items to be stored indefinitely (i.e. + // until the files are deleted) + $defaultLifetime = 0, + + // the main cache directory (the application needs read-write permissions on it) + // if none is specified, a directory is created inside the system temporary directory + $directory = null + ); + +.. note:: + + Since Symfony 3.4, this adapter implements :class:`Symfony\\Component\\Cache\\PruneableInterface`, + allowing for manual :ref:`pruning of expired cache entries ` by + calling its ``prune()`` method. + +.. _`OPcache`: http://php.net/manual/en/book.opcache.php diff --git a/components/cache/cache_invalidation.rst b/components/cache/cache_invalidation.rst index 0ec6b8ba02b..eb5bdf6cfa1 100644 --- a/components/cache/cache_invalidation.rst +++ b/components/cache/cache_invalidation.rst @@ -80,6 +80,16 @@ your fronts and have very fast invalidation checks:: new RedisAdapter('redis://localhost') ); +.. note:: + + Since Symfony 3.4, :class:`Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter` + implements :class:`Symfony\\Component\\Cache\\PruneableInterface`, + enabling manual + :ref:`pruning of expired cache entries ` by + calling its :method:`Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter::prune` + method (assuming the wrapped adapter itself implements + :class:`Symfony\\Component\\Cache\\PruneableInterface`). + .. _cache-component-expiration: Using Cache Expiration diff --git a/components/cache/cache_pools.rst b/components/cache/cache_pools.rst index b28788d0d64..3eca5a945ec 100644 --- a/components/cache/cache_pools.rst +++ b/components/cache/cache_pools.rst @@ -20,6 +20,8 @@ are independent from the actual cache implementation. Therefore, applications can keep using the same cache pool even if the underlying cache mechanism changes from a file system based cache to a Redis or database based cache. +.. _component-cache-creating-cache-pools: + Creating Cache Pools -------------------- @@ -124,8 +126,9 @@ when all items are successfully deleted):: .. tip:: - If the Cache component is used inside a Symfony application, you can remove - all the items of a given cache pool with the following command: + If the cache component is used inside a Symfony application, you can remove + *all items* from the *given pool(s)* using the following command (which resides within + the :ref:`framework bundle `): .. code-block:: terminal @@ -142,4 +145,68 @@ when all items are successfully deleted):: the cache pools, so you must use the ``cache:pool:clear`` command to delete them. -.. _`Doctrine Cache`: https://github.com/doctrine/cache +.. _component-cache-cache-pool-prune: + +Pruning Cache Items +------------------- + +.. versionadded:: 3.4 + + Cache adapter pruning functionality was introduced in Symfony 3.4. + +Some cache pools do not include an automated mechanism for pruning expired cache items. +For example, the :ref:`FilesystemAdaper ` cache +does not remove expired cache items *until an item is explicitly requested and determined to +be expired*, for example, via a call to :method:`Psr\\Cache\\CacheItemPoolInterface::getItem`. +Under certain workloads, this can cause stale cache entries to persist well past their +expiration, resulting in a sizable consumption of wasted disk or memory space from excess, +expired cache items. + +This shortcomming has been solved through the introduction of +:class:`Symfony\\Component\\Cache\\PruneableInterface`, which defines the abstract method +:method:`Symfony\\Component\\Cache\\PruneableInterface::prune`. The +:ref:`ChainAdapter `, +:ref:`FilesystemAdaper `, +:ref:`PdoAdapter `, and +:ref:`PhpFilesAdapter ` all implement this new interface, +allowing manual removal of stale cache items:: + + use Symfony\Component\Cache\Adapter\FilesystemAdapter; + + $cache = new FilesystemAdapter('app.cache'); + // ... do some set and get operations + $cache->prune(); + +The :ref:`ChainAdapter ` implementation does not directly +contain any pruning logic itself. Instead, when calling the chain adapter's +:method:`Symfony\\Component\\Cache\\ChainAdapter::prune` method, the call is deligated to all +its compatibe cache adapters (and those that do not implement ``PruneableInterface`` are +silently ignored):: + + use Symfony\Component\Cache\Adapter\ApcuAdapter; + use Syfmony\Component\Cache\Adapter\ChainAdapter; + use Syfmony\Component\Cache\Adapter\FilesystemAdapter; + use Syfmony\Component\Cache\Adapter\PdoAdapter; + use Syfmony\Component\Cache\Adapter\PhpFilesAdapter; + + $cache = new ChainAdapter(array( + new ApcuAdapter(), // does NOT implement PruneableInterface + new FilesystemAdapter(), // DOES implement PruneableInterface + new PdoAdapter(), // DOES implement PruneableInterface + new PhpFilesAdapter(), // DOES implement PruneableInterface + // ... + )); + + // prune will proxy the call to PdoAdapter, FilesystemAdapter and PhpFilesAdapter, + // while silently skipping ApcuAdapter + $cache->prune(); + +.. tip:: + + If the cache component is used inside a Symfony application, you can prune + *all items* from *all pools* using the following command (which resides within + the :ref:`framework bundle `): + + .. code-block:: terminal + + $ php bin/console cache:pool:prune diff --git a/reference/configuration/framework.rst b/reference/configuration/framework.rst index a6839cf1e36..2fd47b456c3 100644 --- a/reference/configuration/framework.rst +++ b/reference/configuration/framework.rst @@ -1,6 +1,8 @@ .. index:: single: Configuration reference; Framework +.. _framework-bundle-configuration: + FrameworkBundle Configuration ("framework") =========================================== From eb70a365ee34aa47997694da9aedf615a5c443bd Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 23 Jan 2018 08:33:34 +0100 Subject: [PATCH 2/5] Wrapped long lines --- components/cache/adapters/apcu_adapter.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/components/cache/adapters/apcu_adapter.rst b/components/cache/adapters/apcu_adapter.rst index 0b5c9b30bdf..54507ccfc66 100644 --- a/components/cache/adapters/apcu_adapter.rst +++ b/components/cache/adapters/apcu_adapter.rst @@ -7,17 +7,17 @@ APCu Cache Adapter ================== -This adapter is a high-performance, shared memory cache. It can *significantly* increase -an application's performance, as its cache contents are stored in shared memory, a component -appreciably faster than many others, such as the filesystem. +This adapter is a high-performance, shared memory cache. It can *significantly* +increase an application's performance, as its cache contents are stored in shared +memory, a component appreciably faster than many others, such as the filesystem. .. caution:: **Requirement:** The `APCu extension`_ must be installed and active to use this adapter. -The ApcuAdapter can optionally be provided a namespace, default cache lifetime, and cache -items version string as constructor arguments:: +The ApcuAdapter can optionally be provided a namespace, default cache lifetime, +and cache items version string as constructor arguments:: use Symfony\Component\Cache\Adapter\ApcuAdapter; @@ -47,4 +47,4 @@ items version string as constructor arguments:: means cache operations (such as additions, deletions, etc) using the CLI will not be available under the FPM or CGI SAPIs. -.. _`APCu extension`: https://pecl.php.net/package/APCu \ No newline at end of file +.. _`APCu extension`: https://pecl.php.net/package/APCu From 5bea1e6c8b58700a2d186fbf63a90962d8e70906 Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 23 Jan 2018 08:36:00 +0100 Subject: [PATCH 3/5] Fixed a typo --- components/cache/adapters/chain_adapter.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/cache/adapters/chain_adapter.rst b/components/cache/adapters/chain_adapter.rst index a91ab859edc..7a64064332b 100644 --- a/components/cache/adapters/chain_adapter.rst +++ b/components/cache/adapters/chain_adapter.rst @@ -10,7 +10,7 @@ Chain Cache Adapter This adapter allows combining any number of the other :ref:`available cache adapters `. Cache items are fetched from the first adapter containing them and cache items are saved to all the -given adapters. This exposes a simple and efficient method for creating a layeted cache. +given adapters. This exposes a simple and efficient method for creating a layered cache. The ChainAdapter must be provided an array of adapters and optionally a maximum cache lifetime as its constructor arguments:: From 1322ffdbe649cf16d636b29b1bdb45c5e02b391a Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 23 Jan 2018 08:38:37 +0100 Subject: [PATCH 4/5] Typos and wrapped long lines --- .../cache/adapters/filesystem_adapter.rst | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/components/cache/adapters/filesystem_adapter.rst b/components/cache/adapters/filesystem_adapter.rst index f7aa7e495d5..c391de197a6 100644 --- a/components/cache/adapters/filesystem_adapter.rst +++ b/components/cache/adapters/filesystem_adapter.rst @@ -14,7 +14,7 @@ a collection of directories on a locally mounted filesystem. .. tip:: - The performance of this adapter can be greatly increased by utalizing a + The performance of this adapter can be greatly increased by utilizing a temporary, in-memory filesystem, such as `tmpfs`_ on Linux, or one of the many other `RAM disk solutions`_ available. @@ -41,16 +41,19 @@ and cache root path as constructor parameters:: .. caution:: - The overhead of filesystem IO often makes this adapter one of the *slower* choices. If throughput is - paramount, the in-memory adapters (:ref:`Apcu `, :ref:`Memcached `, - and :ref:`Redis `) or the database adapters (:ref:`Doctrine ` and - :ref:`PDO `) are recommended. + The overhead of filesystem IO often makes this adapter one of the *slower* + choices. If throughput is paramount, the in-memory adapters + (:ref:`Apcu `, :ref:`Memcached `, and + :ref:`Redis `) or the database adapters + (:ref:`Doctrine ` and :ref:`PDO `) + are recommended. .. note:: - Since Symfony 3.4, this adapter implements :class:`Symfony\\Component\\Cache\\PruneableInterface`, - enabling manual :ref:`pruning of expired cache items ` by + Since Symfony 3.4, this adapter implements + :class:`Symfony\\Component\\Cache\\PruneableInterface`, enabling manual + :ref:`pruning of expired cache items ` by calling its ``prune()`` method. .. _`tmpfs`: https://wiki.archlinux.org/index.php/tmpfs -.. _`RAM disk solutions`: https://en.wikipedia.org/wiki/List_of_RAM_drive_software \ No newline at end of file +.. _`RAM disk solutions`: https://en.wikipedia.org/wiki/List_of_RAM_drive_software From 54a1e62569f30cc589f9330ef09009a29ed0cd9e Mon Sep 17 00:00:00 2001 From: Javier Eguiluz Date: Tue, 23 Jan 2018 08:40:55 +0100 Subject: [PATCH 5/5] Typo --- components/cache/cache_pools.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/cache/cache_pools.rst b/components/cache/cache_pools.rst index 3eca5a945ec..4feec6c96b5 100644 --- a/components/cache/cache_pools.rst +++ b/components/cache/cache_pools.rst @@ -179,7 +179,7 @@ allowing manual removal of stale cache items:: The :ref:`ChainAdapter ` implementation does not directly contain any pruning logic itself. Instead, when calling the chain adapter's -:method:`Symfony\\Component\\Cache\\ChainAdapter::prune` method, the call is deligated to all +:method:`Symfony\\Component\\Cache\\ChainAdapter::prune` method, the call is delegated to all its compatibe cache adapters (and those that do not implement ``PruneableInterface`` are silently ignored)::