Important
You are browsing the documentation for version 3.1 of OroCommerce, OroCRM and OroPlatform, which is no longer maintained. Read version 5.1 (the latest LTS version) of the Oro documentation to get up-to-date information.
See our Release Process documentation for more information on the currently supported and upcoming releases.
Cache in Oro Application¶
The OroCacheBundle
is responsible for operations with various kinds of caches.
Abstract Cache Services¶
There are two abstract services you can use as a parent for your cache services:
oro.file_cache.abstract
- this cache should be used for caching data private for each node in a web farmoro.cache.abstract
- this cache should be used for caching data that need to be shared between nodes in a web farm
The following example shows how these services can be used:
1services:
2 acme.test.cache:
3 public: false
4 parent: oro.cache.abstract
5 calls:
6 - [ setNamespace, [ 'acme_test' ] ]
Also each of these abstract services can be re-declared in the application configuration file, for example:
1services:
2 oro.cache.abstract:
3 abstract: true
4 class: Oro\Bundle\CacheBundle\Provider\PhpFileCache
5 arguments: [%kernel.cache_dir%/oro_data]
The oro.cache.abstract.without_memory_cache service is always declared automatically based on oro.cache.abstract service.
Warm Up Config Cache¶
The purpose is to update only cache that will be needed by the application without updating the cache of those resources, that have not been changed. This gives a big performance over the approach when the all cache is updated. Cache warming occurs in debug mode whenever you updated the resource files.
The following example shows how this services can be used:
1```yaml
2# To register your config dumper:
3oro.config.dumper:
4 class: Oro\Example\Dumper\CumulativeConfigMetadataDumper
5 public: false
6
7# To register your config warmer with oro.config_cache_warmer.provider tag:
8oro.configuration.provider.test:
9 class: Oro\Example\Dumper\ConfigurationProvider
10 tags:
11 - { name: oro.config_cache_warmer.provider, dumper: 'oro.config.dumper' }
12
13```
14
15```php
16<?php
17
18namespace Oro\Example\Dumper;
19
20use Symfony\Component\DependencyInjection\ContainerBuilder;
21
22use Oro\Component\Config\Dumper\ConfigMetadataDumperInterface;
23use Oro\Bundle\CacheBundle\Provider\ConfigCacheWarmerInterface;
24
25class CumulativeConfigMetadataDumper implements ConfigMetadataDumperInterface
26{
27
28 /**
29 * Write meta file with resources related to specific config type
30 *
31 * @param ContainerBuilder $container container with resources to dump
32 */
33 public function dump(ContainerBuilder $container)
34 {
35 }
36
37 /**
38 * Check are config resources fresh?
39 *
40 * @return bool true if data in cache is present and up to date, false otherwise
41 */
42 public function isFresh()
43 {
44 return true;
45 }
46}
47
48class ConfigurationProvider implements ConfigCacheWarmerInterface
49{
50 /**
51 * @param ContainerBuilder $containerBuilder
52 */
53 public function warmUpResourceCache(ContainerBuilder $containerBuilder)
54 {
55 // some logic
56 $resource = new CumulativeResource();
57 $containerBuilder->addResource($resource);
58 }
59}
60```
Caching Policy¶
Memory Based Cache¶
One of the most important things when dealing with caches is proper cache invalidation. When using memory based cache, we need to make sure that we do not keep old values in the memory. Consider this example:
1<?php
2
3class LocalizationManager
4{
5 /** @var \Doctrine\Common\Cache\ArrayCache */
6 private $cacheProvider;
7
8 public function getLocalization($id)
9 {
10 $localization = $this->cacheProvider->fetch($id);
11
12 // ... all other operations, fetch from DB if cache is empty
13 // ... save in cache data from DB
14
15 return $localization;
16 }
17
18}
Since $cacheProvider
in our example is an implementation of memory
ArrayCache
, we will keep the data there until the process ends. With
HTTP request this would work perfectly well, but when our
LocalizationManager
is used in some long-running cli
processes, we have to manually clear memory cache after every change
with Localizations. Missing cache clearing for any of these cases leads
to outdated data in LocalizationManager
.
Cache Chaining¶
The solution to the issue mentioned above is to keep a healthy balance between the fast and shared cache. It is implemented in the ChainCache class.
1<?php
2
3namespace Oro\Bundle\CacheBundle\Provider;
4
5use Doctrine\Common\Cache\ArrayCache;
6use Doctrine\Common\Cache\ChainCache;
7
8class MemoryCacheChain extends ChainCache
9{
10 /**
11 * {@inheritdoc}
12 */
13 public function __construct($cacheProviders = [])
14 {
15 if (PHP_SAPI !== 'cli') {
16 array_unshift($cacheProviders, new ArrayCache());
17 }
18
19 parent::__construct($cacheProviders);
20 }
21}
This class checks whether a request comes from the CLI. If not, the
memory ArrayCache
is added to the top of the cache providers which
are being used for caching. With these priorities set, all HTTP requests
gain performance when dealing with caches in memory and the CLI
processes have no issues with the outdated data as they use the
persistent cache.
Default Cache Implementation¶
There are two abstract services you can use
as a parent for your cache services. Default implementations are
following: - for CLI requests: MemoryCacheChain
with only
Oro\Bundle\CacheBundle\Provider\FilesystemCache
as a cache provider
- for other requests: MemoryCacheChain
with ArrayCache
on the
top of FilesystemCache
For services based on oro.cache.abstract.without_memory_cache the MemoryCacheChain is not used.
Caching of Symfony Validation Rules¶
By default, rules for Symfony Validation Component are cached using
oro.cache.abstract
service, but you can change this to make
validation caching suit some custom requirements. To do this, you need
to redefine the oro_cache.provider.validation
service.
Caching Data based on Complex Objects¶
Cache Hit Ratio is an important measure of cache efficiency. Choosing the right Cache Key might be a complex task, especially when the cache key should depend on the data stored in a Complex Object. Cache key generation strategy can vary in different cases and rely on different fields of the same object. To configure cache metadata for different scopes, use Resources/config/oro/cache_metadata.yml files that can be located in any bundle.
Here is an example of such configuration:
1 Oro\Bundle\OrderBundle\Entity\OrderAddress:
2 attributes:
3 id:
4 groups: ['shipping_context']
5 country:
6 groups: ['shipping_context', 'promotion']
Data from this configuration is used by the oro.cache.generator.object_cache_key
service to provide cache keys for the
given object and scope.