Skip to content

[Cache] Add chapter about invalidation, tags, etc. #6947

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 20, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions components/cache.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
The Cache Component
===================

The Cache component provides a strict `PSR-6`_ implementation for adding
The Cache component provides an extended `PSR-6`_ implementation for adding
cache to your applications. It is designed to have a low overhead and it
ships with ready to use adapters for the most common caching backends.

Expand Down Expand Up @@ -42,7 +42,7 @@ meaning of some key concepts:
Basic Usage
-----------

This component is a strict implementation of `PSR-6`_, which means that the API
This component is an implementation of `PSR-6`_, which means that its basic API
is the same as defined in the standard. Before starting to cache information,
create the cache pool using any of the built-in adapters. For example, to create
a filesystem-based cache, instantiate :class:`Symfony\\Component\\Cache\\Adapter\\FilesystemAdapter`::
Expand Down
89 changes: 89 additions & 0 deletions components/cache/cache_invalidation.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
.. index::
single: Cache; Invalidation
single: Cache; Tags

Cache Invalidation
==================

Cache invalidation is the process of removing all cached items related to a
change in the state of your model. The most basic kind of invalidation is direct
items deletion. But when the state of a primary resource has spread accross
several cached items, keeping them in sync can be difficult.

The Symfony Cache component provides two mechanisms to help solve this problem:

* Tags based invalidation for managing data dependencies;
* Expiration based invalidation for time related dependencies.

.. versionadded:: 3.2
Tags based invalidation was introduced in Symfony 3.2.

Using Cache Tags
----------------

To benefit from tags based invalidation, you need to attach the proper tags to
each cached items. Each tag is a plain string identifier that you can use at any
time to trigger the removal of all items that had this tag attached to them.

To attach tags to cached items, you need to use the
:method:`Symfony\\Component\\Cache\\CacheItem::tag` method that is implemented by
cache items, as returned by cache adapters::

$item = $cache->getItem('cache_key');
// ...
// add one or more tags
$item->tag('tag_1');
$item->tag(array('tag_2', 'tag_3'));
$cache->save($item);

If ``$cache`` implements :class:`Symfony\\Component\\Cache\\TagAwareAdapterInterface`,
you can invalidate the cached items by calling
:method:`Symfony\\Component\\Cache\\TagAwareAdapterInterface::invalidateTags`::

// invalidate all items related to `tag_2`
$cache->invalidateTags('tag_2');
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the comment says tag_1 but the code says tag_2


// or invalidate all items related to `tag_1` or `tag_3`
$cache->invalidateTags(array('tag_1', 'tag_3'));

// if you know the cache key, you can of course delete directly
$cache->deleteItem('cache_key');

Using tags invalidation is very useful when tracking cache keys becomes difficult.

Tag Aware Adapters
~~~~~~~~~~~~~~~~~~

To store tags, you need to wrap a cache adapter with the
:class:`Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter` class or implement
:class:`Symfony\\Component\\Cache\\Adapter\\TagAwareAdapterInterface` and its only
:method:`Symfony\\Component\\Cache\\Adapter\\TagAwareAdapterInterface::invalidateTags`
method.

The :class:`Symfony\\Component\\Cache\\Adapter\\TagAwareAdapter` class implements
instantaneous invalidation (time complexity is ``O(N)`` where ``N`` is the number
of invalidated tags). It needs one or two cache adapters: the first required
one is used to store cached items; the second optional one is used to store tags
and their invalidation version number (conceptually similar to their latest
invalidation date). When only one adapter is used, items and tags are all stored
in the same place. By using two adapters, you can e.g. store some big cached items
on the filesystem or in the database and keep tags in a Redis database to sync all
your fronts and have very fast invalidation checks::

use Symfony\Component\Cache\Adapter\TagAwareAdapter;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a great example and very well explained!!

use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;

$cache = new TagAwareAdapter(
// Adapter for cached items
new FilesystemAdapter(),
// Adapter for tags
new RedisAdapter('redis://localhost')
);

Using Cache Expiration
----------------------

If your data is valid only for a limited period of time, you can specify their
lifetime or their expiration date with the PSR-6 interface, as explained in the
:doc:`/components/cache/cache_items` article.
2 changes: 1 addition & 1 deletion components/cache/cache_items.rst
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ In the Cache component they are represented by the
Cache Item Keys and Values
--------------------------

The **key** of a cache item is a UTF-8 encoded string which acts as its
The **key** of a cache item is a plain string which acts as its
identifier, so it must be unique for each cache pool. You can freely choose the
keys, but they should only contain letters (A-Z, a-z), numbers (0-9) and the
``_`` and ``.`` symbols. Other common symbols (such as ``{``, ``}``, ``(``,
Expand Down
38 changes: 33 additions & 5 deletions components/cache/cache_pools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
single: APC Cache, APCu Cache
single: Doctrine Cache
single: Redis Cache
single: PDO Cache, Doctrine DBAL Cache

Cache Pools
===========
Expand Down Expand Up @@ -41,7 +42,7 @@ Filesystem Cache Adapter
~~~~~~~~~~~~~~~~~~~~~~~~

This adapter is useful when you want to improve the application performance but
can't install tools like APC or Redis in the server. This adapter stores the
can't install tools like APCu or Redis in the server. This adapter stores the
contents as regular files in a set of directories on the local file system::

use Symfony\Component\Cache\Adapter\FilesystemAdapter;
Expand Down Expand Up @@ -83,7 +84,7 @@ degrade performance significantly::
Redis Cache Adapter
~~~~~~~~~~~~~~~~~~~

This adapter stores the contents in the memory of the server. Unlike the APCu
This adapter stores the contents in the memory of a Redis server. Unlike the APCu
adapter, it's not limited to the shared memory of the current server, so you can
store contents in a cluster of servers if needed.

Expand All @@ -102,6 +103,36 @@ the ``\Redis``, ``\RedisArray``, ``\RedisCluster`` or ``\Predis`` classes::
$defaultLifetime = 0
);

The :method:`Symfony\\Component\\Cache\\Adapter\\RedisAdapter::createConnection`
helper allows creating a connection to a Redis server using a DSN configuration::

$redisConnection = RedisAdapter::createConnection('redis://localhost');

See the method's docblock for more options.

PDO & Doctrine DBAL Cache Adapter
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

This adapter stores the cached items a SQL database accessed through a PDO or a
Doctrine DBAL connection::

use Symfony\Component\Cache\Adapter\PdoAdapter;

$cache = new PdoAdapter(
// a PDO, a Doctrine DBAL connection or DSN for lazy connecting through PDO
$databaseConnectionOrDSN,
// the string prefixed to the keys of the items stored in this cache
$namespace = '',
// in seconds; applied to cache items that don't define their own lifetime
// 0 means to store the cache items indefinitely (i.e. until the database is cleared)
$defaultLifetime = 0,
// an array of options for configuring the database connection
$options = array()
);

.. versionadded:: 3.2
The PDO & Doctrine DBAL adapter was introduced in Symfony 3.2.

Chain Cache Adapter
~~~~~~~~~~~~~~~~~~~

Expand Down Expand Up @@ -141,9 +172,6 @@ that external cache and save them in the Symfony cache of your application::
The adapter accepts two additional optional arguments: the namespace (``''`` by
default) and the default lifetime (``0`` by default).

Another use case for this adapter is to get statistics and metrics about the
cache hits (``getHits()``) and misses (``getMisses()``).

Doctrine Cache Adapter
~~~~~~~~~~~~~~~~~~~~~~

Expand Down