Skip to content

Latest commit

 

History

History
290 lines (215 loc) · 13.2 KB

caching-data.md

File metadata and controls

290 lines (215 loc) · 13.2 KB

Data Caching

Data caching is about storing some PHP variable in cache and retrieving it later from cache. It is also the foundation for more advanced caching features, such as query caching and page caching.

The following code is a typical usage pattern of data caching, where $cache refers to a cache component:

// try retrieving $data from cache
$data = $cache->get($key);

if ($data === false) {

    // $data is not found in cache, calculate it from scratch

    // store $data in cache so that it can be retrieved next time
    $cache->set($key, $data);
}

// $data is available here

Cache Components

Data caching relies on the so-called cache components which represent various cache storage, such as memory, files, databases.

Cache components are usually registered as application components so that they can be globally configurable and accessible. The following code shows how to configure the cache application component to use memcached with two cache servers:

'components' => [
    'cache' => [
        'class' => 'yii\caching\MemCache',
        'servers' => [
            [
                'host' => 'server1',
                'port' => 11211,
                'weight' => 100,
            ],
            [
                'host' => 'server2',
                'port' => 11211,
                'weight' => 50,
            ],
        ],
    ],
],

You can then access the above cache component using the expression Yii::$app->cache.

Because all cache components support the same set of APIs, you can swap the underlying cache component with a different one by reconfiguring it in the application configuration without modifying the code that uses the cache. For example, you can modify the above configuration to use [[yii\caching\ApcCache|APC cache]]:

'components' => [
    'cache' => [
        'class' => 'yii\caching\ApcCache',
    ],
],

Tip: You can register multiple cache application components. The component named cache is used by default by many cache-dependent classes (e.g. [[yii\web\UrlManager]]).

Supported Cache Storage

Yii supports a wide range of cache storage. The following is a summary:

  • [[yii\caching\ApcCache]]: uses PHP APC extension. This option can be considered as the fastest one when dealing with cache for a centralized thick application (e.g. one server, no dedicated load balancers, etc.).
  • [[yii\caching\DbCache]]: uses a database table to store cached data. To use this cache, you must create a table as specified in [[yii\caching\DbCache::cacheTable]].
  • [[yii\caching\DummyCache]]: serves as a cache placeholder which does no real caching. The purpose of this component is to simplify the code that needs to check the availability of cache. For example, during development or if the server doesn't have actual cache support, you may configure a cache component to use this cache. When an actual cache support is enabled, you can switch to use the corresponding cache component. In both cases, you may use the same code Yii::$app->cache->get($key) to attempt retrieving data from the cache without worrying that Yii::$app->cache might be null.
  • [[yii\caching\FileCache]]: uses standard files to store cached data. This is particular suitable to cache large chunk of data, such as page content.
  • [[yii\caching\MemCache]]: uses PHP memcache and memcached extensions. This option can be considered as the fastest one when dealing with cache in a distributed applications (e.g. with several servers, load balancers, etc.)
  • [[yii\redis\Cache]]: implements a cache component based on Redis key-value store (redis version 2.6.12 or higher is required).
  • [[yii\caching\WinCache]]: uses PHP WinCache (see also) extension.
  • [[yii\caching\XCache]]: uses PHP XCache extension.
  • [[yii\caching\ZendDataCache]]: uses Zend Data Cache as the underlying caching medium.

Tip: You may use different cache storage in the same application. A common strategy is to use memory-based cache storage to store data that is small but constantly used (e.g. statistical data), and use file-based or database-based cache storage to store data that is big and less frequently used (e.g. page content).

Cache APIs

All cache components have the same base class [[yii\caching\Cache]] and thus support the following APIs:

  • [[yii\caching\Cache::get()|get()]]: retrieves a data item from cache with a specified key. A false value will be returned if the data item is not found in the cache or is expired/invalidated.
  • [[yii\caching\Cache::set()|set()]]: stores a data item identified by a key in cache.
  • [[yii\caching\Cache::add()|add()]]: stores a data item identified by a key in cache if the key is not found in the cache.
  • [[yii\caching\Cache::mget()|mget()]]: retrieves multiple data items from cache with the specified keys.
  • [[yii\caching\Cache::mset()|mset()]]: stores multiple data items in cache. Each item is identified by a key.
  • [[yii\caching\Cache::madd()|madd()]]: stores multiple data items in cache. Each item is identified by a key. If a key already exists in the cache, the data item will be skipped.
  • [[yii\caching\Cache::exists()|exists()]]: returns a value indicating whether the specified key is found in the cache.
  • [[yii\caching\Cache::delete()|delete()]]: removes a data item identified by a key from the cache.
  • [[yii\caching\Cache::flush()|flush()]]: removes all data items from the cache.

Some cache storage, such as MemCache, APC, support retrieving multiple cached values in a batch mode, which may reduce the overhead involved in retrieving cached data. The APIs [[yii\caching\Cache::mget()|mget()]] and [[yii\caching\Cache::madd()|madd()]] are provided to exploit this feature. In case the underlying cache storage does not support this feature, it will be simulated.

Because [[yii\caching\Cache]] implements ArrayAccess, a cache component can be used like an array. The followings are some examples:

$cache['var1'] = $value1;  // equivalent to: $cache->set('var1', $value1);
$value2 = $cache['var2'];  // equivalent to: $value2 = $cache->get('var2');

Cache Keys

Each data item stored in cache is uniquely identified by a key. When you store a data item in cache, you have to specify a key for it. Later when you retrieve the data item from cache, you should provide the corresponding key.

You may use a string or an arbitrary value as a cache key. When a key is not a string, it will be automatically serialized into a string.

A common strategy of defining a cache key is to include all determining factors in terms of an array. For example, [[yii\db\Schema]] uses the following key to cache schema information about a database table:

[
    __CLASS__,              // schema class name
    $this->db->dsn,         // DB connection data source name
    $this->db->username,    // DB connection login user
    $name,                  // table name
];

As you can see, the key includes all necessary information needed to uniquely specify a database table.

When the same cache storage is used by different applications, you should specify a unique cache key prefix for each application to avoid conflicts of cache keys. This can be done by configuring the [[yii\caching\Cache::keyPrefix]] property. For example, in the application configuration you can write the following code:

'components' => [
    'cache' => [
        'class' => 'yii\caching\ApcCache',
        'keyPrefix' => 'myapp',       // a unique cache key prefix
    ],
],

To ensure interoperability, only alphanumeric characters should be used.

Cache Expiration

A data item stored in a cache will remain there forever unless it is removed because of some caching policy enforcement (e.g. caching space is full and the oldest data are removed). To change this behavior, you can provide an expiration parameter when calling [[yii\caching\Cache::set()|set()]] to store a data item. The parameter indicates for how many seconds the data item can remain valid in the cache. When you call [[yii\caching\Cache::get()|get()]] to retrieve the data item, if it has passed the expiration time, the method will return false, indicating the data item is not found in the cache. For example,

// keep the data in cache for at most 45 seconds
$cache->set($key, $data, 45);

sleep(50);

$data = $cache->get($key);
if ($data === false) {
    // $data is expired or is not found in the cache
}

Cache Dependencies

Besides expiration setting, cached data item may also be invalidated by changes of the so-called cache dependencies. For example, [[yii\caching\FileDependency]] represents the dependency of a file's modification time. When this dependency changes, it means the corresponding file is modified. As a result, any outdated file content found in the cache should be invalidated and the [[yii\caching\Cache::get()|get()]] call should return false.

Cache dependencies are represented as objects of [[yii\caching\Dependency]] descendant classes. When you call [[yii\caching\Cache::set()|set()]] to store a data item in the cache, you can pass along an associated cache dependency object. For example,

// Create a dependency on the modification time of file example.txt.
$dependency = new \yii\caching\FileDependency(['fileName' => 'example.txt']);

// The data will expire in 30 seconds.
// It may also be invalidated earlier if example.txt is modified.
$cache->set($key, $data, 30, $dependency);

// The cache will check if the data has expired.
// It will also check if the associated dependency was changed.
// It will return false if any of these conditions is met.
$data = $cache->get($key);

Below is a summary of the available cache dependencies:

  • [[yii\caching\ChainedDependency]]: the dependency is changed if any of the dependencies on the chain is changed.
  • [[yii\caching\DbDependency]]: the dependency is changed if the query result of the specified SQL statement is changed.
  • [[yii\caching\ExpressionDependency]]: the dependency is changed if the result of the specified PHP expression is changed.
  • [[yii\caching\FileDependency]]: the dependency is changed if the file's last modification time is changed.
  • [[yii\caching\GroupDependency]]: marks a cached data item with a group name. You may invalidate the cached data items with the same group name all at once by calling [[yii\caching\GroupDependency::invalidate()]].

Query Caching

Query caching is a special caching feature built on top of data caching. It is provided to cache the result of database queries.

Query caching requires a [[yii\db\Connection|DB connection]] and a valid cache application component. The basic usage of query caching is as follows, assuming $db is a [[yii\db\Connection]] instance:

$duration = 60;     // cache query results for 60 seconds.
$dependency = ...;  // optional dependency

$db->beginCache($duration, $dependency);

// ...performs DB queries here...

$db->endCache();

As you can see, any SQL queries in between the beginCache() and endCache() calls will be cached. If the result of the same query is found valid in the cache, the query will be skipped and the result will be served from the cache instead.

Query caching can be used for DAO as well as ActiveRecord.

Info: Some DBMS (e.g. MySQL) also support query caching on the DB server side. You may choose to use either query caching mechanism. The query caching described above has the advantage that you may specify flexible cache dependencies and are potentially more efficient.

Configurations

Query caching has two configurable options through [[yii\db\Connection]]:

  • [[yii\db\Connection::queryCacheDuration|queryCacheDuration]]: this represents the number of seconds that a query result can remain valid in the cache. The duration will be overwritten if you call [[yii\db\Connection::beginCache()]] with an explicit duration parameter.
  • [[yii\db\Connection::queryCache|queryCache]]: this represents the ID of the cache application component. It defaults to 'cache'. Query caching is enabled only when there is a valid cache application component.

Limitations

Query caching does not work with query results that contain resource handlers. For example, when using the BLOB column type in some DBMS, the query result will return a resource handler for the column data.

Some caching storage has size limitation. For example, memcache limits the maximum size of each entry to be 1MB. Therefore, if the size of a query result exceeds this limit, the caching will fail.