際際滷

際際滷Share a Scribd company logo
Symfony Cache Component
speed-up your application with
a new layer of cache
simone damico
software engineer @
@dymissy
sd@ideato.it
Symfony Cache Component
Symfony Cache Component: speed up your application with a new layer of cache
Symfony Cache Component: speed up your application with a new layer of cache
Agenda
How did we cache before
Symfony 3.1?
Symfony Cache Component
Symfony Simple Cache
Real Use Case
In the beginning there was
Cache before Symfony 3.1
 Apc
 Memcache / Memcached
 Redis
Doctrine Cache
doctrine_cache:
class:
DoctrineCommonCacheFilesystemCac
he
arguments:
- '/tmp/doctrine_cache/'
public: true
$cache = $this->get('doctrine_cache');
$feed = $cache->fetch('feed');
if (!$feed) {
$feed = $feedReader->load();
$cache->save('feed', $feed, 60);
}
return $feed;
then Symfony 3.1 was released
Symfony Cache Component
Symfony Cache Component
 Strict implementation of PSR-6: Caching Interface
 Provides adapters for the most common caching
backends
 Compatible with every Doctrine Cache adapter
Symfony Cache Component
Symfony Cache Component
Some of adapters provided:
 Apcu Cache adapter
 Array Cache adapter
 Chain Cache adapter
 Doctrine Cache adapter
 Filesystem Cache adapter
 Memcached Cache adapter
 PDO & Doctrine Cache DBAL adapter
 Php Array Cache adapter
 Proxy Cache adapter
 Redis Cache adapter
PSR-6: Caching Interface
PSR6: Caching Interface
 Goal
Allow developers to create cache-aware libraries that can be
integrated into existing frameworks and systems without the need
for custom development.
 Data
Implementing libraries MUST support all serializable PHP data types,
including: strings, integers, floats, boolean, null, arrays, object
PSR-6: Key Concepts
PSR6: Caching Interface
 Pool
Collection of items in a caching system. The pool is a
logical Repository of all items it contains
 Item
Single key/value pair within a Pool
PSR-6: CacheItemPoolInterface
public function getItem($key);
public function getItems(array $keys = []);
public function hasItem($key);
public function clear();
public function deleteItem($key);
public function deleteItems(array $keys);
public function save(CacheItemInterface
$item);
public function
saveDeferred(CacheItemInterface $item);
public function commit();
PSR-6: CacheItemInterface
public function getKey();
public function get();
public function isHit();
public function set($value);
public function expiresAt($expiration);
public function expiresAfter($time);
Symfony Cache Component: Key Concepts
Symfony Cache Component
 Pool
 Item
 Adapter
SymfonyComponentCacheAdapterAdapterInterface
SymfonyComponentCacheCacheItem
SymfonyComponentCacheAdapter*Adapter
Symfony Cache Component
symfony_cache:
class:
SymfonyComponentCacheAdapter
FilesystemAdapter
arguments:
- ''
- 0
- '/tmp/cache/'
public: true
$cache = $this->get('symfony_cache');
$cacheItem = $cache->getItem('feed');
if($cacheItem->isHit()) {
return $cacheItem->get();
}
$feed = $feedReader->load();
$cacheItem->set($feed);
$cacheItem->expiresAfter(60);
$cache->save($cacheItem);
return $feed;
Symfony Cache Component
symfony_cache:
class:
SymfonyComponentCacheAdapter
FilesystemAdapter
arguments:
- ''
- 0
- '/tmp/symfony_cache/'
public: true
$cache = $this->get('symfony_cache');
$cacheItem = $cache->getItem('feed');
if($cacheItem->isHit()) {
return $cacheItem->get();
}
$feed = $feedReader->load();
$cacheItem->set($feed);
$cacheItem->expiresAfter(60);
$cache->save($cacheItem);
return $feed;
1
Symfony Cache Component
symfony_cache:
class:
SymfonyComponentCacheAdapter
FilesystemAdapter
arguments:
- ''
- 0
- '/tmp/symfony_cache/'
public: true
$cache = $this->get('symfony_cache');
$cacheItem = $cache->getItem('feed');
if($cacheItem->isHit()) {
return $cacheItem->get();
}
$feed = $feedReader->load();
$cacheItem->set($feed);
$cacheItem->expiresAfter(60);
$cache->save($cacheItem);
return $feed;
2
Symfony Cache Component
symfony_cache:
class:
SymfonyComponentCacheAdapter
FilesystemAdapter
arguments:
- ''
- 0
- '/tmp/symfony_cache/'
public: true
$cache = $this->get('symfony_cache');
$cacheItem = $cache->getItem('feed');
if($cacheItem->isHit()) {
return $cacheItem->get();
}
$feed = $feedReader->load();
$cacheItem->set($feed);
$cacheItem->expiresAfter(60);
$cache->save($cacheItem);
return $feed;
3
Symfony Cache Component
symfony_cache:
class:
SymfonyComponentCacheAdapter
FilesystemAdapter
arguments:
- ''
- 0
- '/tmp/symfony_cache/'
public: true
$cache = $this->get('symfony_cache');
$cacheItem = $cache->getItem('feed');
if($cacheItem->isHit()) {
return $cacheItem->get();
}
$feed = $feedReader->load();
$cacheItem->set($feed);
$cacheItem->expiresAfter(60);
$cache->save($cacheItem);
return $feed;
4
Symfony Cache Component
symfony_cache:
class:
SymfonyComponentCacheAdapter
FilesystemAdapter
arguments:
- ''
- 0
- '/tmp/symfony_cache/'
public: true
$cache = $this->get('symfony_cache');
$cacheItem = $cache->getItem('feed');
if($cacheItem->isHit()) {
return $cacheItem->get();
}
$feed = $feedReader->load();
$cacheItem->set($feed);
$cacheItem->expiresAfter(60);
$cache->save($cacheItem);
return $feed;
5
Symfony Cache Component
symfony_cache:
class:
SymfonyComponentCacheAdapter
FilesystemAdapter
arguments:
- ''
- 0
- '/tmp/symfony_cache/'
public: true
$cache = $this->get('symfony_cache');
$cacheItem = $cache->getItem('feed');
if($cacheItem->isHit()) {
return $cacheItem->get();
}
$feed = $feedReader->load();
$cacheItem->set($feed);
$cacheItem->expiresAfter(60);
$cache->save($cacheItem);
return $feed;
6
OK. Cool. But
can we do it in a simpler way?
PSR-16: Common Interface for Caching Libraries
PSR16: Caching Interface
 Goal
Simplify PSR-6 Interface for easier use cases
 Data
Implementing libraries MUST support all serializable PHP
data types, including: strings, integers, floats, boolean,
null, arrays, object
PSR-16: CacheInterface
public function get($key, $default = null);
public function set($key, $value, $ttl = null);
public function delete($key);
public function clear();
public function getMultiple($keys, $default = null);
public function setMultiple($values, $ttl = null);
public function deleteMultiple($keys);
public function has($key);
Symfony Simple Cache
Symfony Simple Cache
 Available from Symfony 3.3
 Implementation of PSR-16
Symfony Simple Cache
simple_cache:
class:
SymfonyComponentCacheSimpleF
ilesystemCache
arguments:
- ''
- 0
- '/tmp/cache/'
public: true
$cache = $this->get('simple_cache');
if ($cache->has('feed')) {
return $cache->get('feed');
}
$feed = $feedReader->load();
$cache->set('feed', $feed, 60);
return $feed;
Symfony Simple Cache
simple_cache:
class:
SymfonyComponentCacheSimpleF
ilesystemCache
arguments:
- ''
- 0
- '/tmp/cache/'
public: true
$cache = $this->get('simple_cache');
if ($cache->has('feed')) {
return $cache->get('feed');
}
$feed = $feedReader->load();
$cache->set('feed', $feed, 60);
return $feed;
1
Symfony Simple Cache
simple_cache:
class:
SymfonyComponentCacheSimpleF
ilesystemCache
arguments:
- ''
- 0
- '/tmp/cache/'
public: true
$cache = $this->get('simple_cache');
if ($cache->has('feed')) {
return $cache->get('feed');
}
$feed = $feedReader->load();
$cache->set('feed', $feed, 60);
return $feed;
2
Symfony Simple Cache
simple_cache:
class:
SymfonyComponentCacheSimpleF
ilesystemCache
arguments:
- ''
- 0
- '/tmp/cache/'
public: true
$cache = $this->get('simple_cache');
if ($cache->has('feed')) {
return $cache->get('feed');
}
$feed = $feedReader->load();
$cache->set('feed', $feed, 60);
return $feed;
3
Symfony Simple Cache
$cache = $this->get('simple_cache');
if ($cache->has('feed')) {
return $cache->get('feed');
}
$feed = $feedReader->load();
$cache->set('feed', $feed, 60);
return $feed;
$cache = $this->get('symfony_cache');
$cacheItem = $cache->getItem('feed');
if($cacheItem->isHit()) {
return $cacheItem->get();
}
$feed = $feedReader->load();
$cacheItem->set($feed);
$cacheItem->expiresAfter(60);
$cache->save($cacheItem);
return $feed;
Cache Component Simple Cache
Simple Cache looks simpler than Cache Component.
Why should we use the component?
Symfony Cache Component
Symfony Cache Component
 Tags
 ChainCache Adapter
 ProxyCache Adapter
 Symfony FrameworkBundle Integration
Symfony Cache Component
Symfony Cache Component
 Tags
 ChainCache Adapter
 ProxyCache Adapter
 Symfony FrameworkBundle Integration
Real use case scenario
Domain
Real Use Case Scenario
 Thousands of unique visitors per day
 Millions of page requested per day
 Distributed system architecture
 Different layers of caching
 Performance matters
Domain
Real Use Case Scenario
 Different caching strategies:
- Slow queries with low refresh rate
- Loading data from external APIs with
low rate limit
- CPU intensive tasks
-
Real use case scenario
cache:
default_redis_provider: "%app_cache_redis_provider%"
default_memcached_provider: "%app_cache_memcached_provider%"
pools:
app.cache.rating:
adapter: cache.adapter.redis
default_lifetime: 21600
app.cache.api:
adapter: cache.adapter.memcached
default_lifetime: 3600
app.cache.customer:
adapter: cache.app #defaults to cache.adapter.filesystem
default_lifetime: 86400
public: true
config.yml
Real use case scenario
$cache = $this->get('app.cache.customer');
$cacheItem = $cache->getItem('customer14');
if ($cacheItem->isHit()) {
return $cacheItem->get();
}
//...
Use the service in a Controller, UseCase, whatever
Invalidate cache by tags
$cacheItem = $cache->getItem('customer15');
$product = $this->repository->find('customer15');
$cacheItem->set($product);
$cacheItem->tag(['reviews', 'customers', 'customer15']);
$cacheItem->expiresAt(new DateTimeImmutable('tomorrow'));
$cache->save($cacheItem);
//...
$cache->invalidateTags(['customer15']);
$cache->invalidateTags(['customers']);
Tag the cached content in order to invalidate easily
Clear cache pools
$ ./bin/console cache:pool:clear <cache pool or clearer 1> [...<cache
pool or clearer N>]
$ ./bin/console cache:pool:clear app.cache.customer
$ ./bin/console cache:pool:clear app.cache.custom_service
Symfony FrameworkBundle provides specific command for clear cache pools.
Questa 竪 una diapositiva per linserimento di 1 immagine orizzontale con didascalia
Profiler
Profiler
Bonus
Domain
Real Use Case Scenario
 Different caching strategies:
- Slow queries with low refresh rate
- Loading data from external APIs with
low rate limit
- CPU intensive tasks
-
Questa 竪 una diapositiva per linserimento di 1 immagine orizzontale con didascalia
InstragramFeed
Real Use Case Scenario
(https://github.com/ideatosrl/instagram-feed)
 Load recent media from user
 PSR-6 cache decorator
 Easily integration with Symfony
InstragramFeed
InstragramFeed
Questa 竪 una diapositiva per linserimento di 1 immagine orizzontale con didascalia
InstagramCachedFeed
public function getMedia(int $count = self::MEDIA_COUNT, $maxId = null, $minId = null): array
{
$key = sprintf('instagram_feed_%s_%s_%s', $count, $maxId, $minId);
$cacheItem = $this->cache->getItem($key);
if ($cacheItem->isHit()) {
return $cacheItem->get();
}
$feed = $this->instagramFeed->getMedia($count, $maxId, $minId);
$cacheItem->set($feed);
$cacheItem->expiresAfter($this->ttl);
$this->cache->save($cacheItem);
return $feed;
}
Thanks!
http://joind.in/talk/2c738
Simone DAmico
sd@ideato.it
@dymissy
github.com/dymissy
?
We are hiring!
Catch me around here or drop us a line at recruitment@ideato.it
Bonus 2
Questa 竪 una diapositiva per linserimento di 1 immagine orizzontale con didascalia
References
/andreromcke/symfony-meetup-psr6-symfony-31-cache-component
http://www.php-fig.org/psr/psr-6/
http://www.php-fig.org/psr/psr-16/
https://symfony.com/doc/current/components/cache.html
https://github.com/ideatosrl/instagram-feed
Image Credits
http://cybersport.gg/45530/refreshed-cache-in-new-csgo-patch/
https://www.brainvire.com/symfony2-framework-development-services

More Related Content

Symfony Cache Component: speed up your application with a new layer of cache