Pro Yearly is on sale from $80 to $50! »

Symfony Cache: a premium recipe to fast apps

Symfony Cache: a premium recipe to fast apps

Introduced in version 3.1, the Symfony Cache component has 3 promises: performance, safety, and ease of use. Internally and by default, we are already using it out of the box for system caches. It started as a reference implementation of the PSR-6 standard. Along the years and by contributions from the community, it gained a battle-tested feature-set and adapters for many storages. But the next version, 4.2, is the bigger milestone. With some raw examples and benchmarks, let's review how to select the best backend for your needs, wire them in your apps, do tags-based invalidation, protect against cache stampede, etc. Caching might be the most efficient strategy to fast apps.

6baa34bc1e5c347b1003f6abe8691de1?s=128

Nicolas Grekas

February 21, 2019
Tweet

Transcript

  1. Symfony Cache a premium recipe to fast apps #Symfony_Live @nicolasgrekas

  2. None
  3. PSR-6 Caching Interface PHP-FIG – Dec. 2015 Symfony 3.1 –

    May 2016
  4. #Symfony_Live @nicolasgrekas • A common interface caching needs o With

    normalized error handling • Allow for multiple independent extensions PSR-6 Goals
  5. #Symfony_Live @nicolasgrekas • doctrine/cache 70M • symfony/cache 6.5M • zendframework/zend-cache

    4.5M • illuminate/cache 3.6M • tedivm/stash 1.4M Cache on Packagist
  6. #Symfony_Live @nicolasgrekas PSR-6 CacheItemPoolInterface

  7. #Symfony_Live @nicolasgrekas PSR-6 CacheItemInterface

  8. #Symfony_Live @nicolasgrekas PSR-6 Typical Lifecycle

  9. Symfony Cache What else?

  10. #Symfony_Live @nicolasgrekas • A dual PSR-6 and PSR-16 implementation •

    With strict public API and error handling • With exclusive extra features • Tuned for performance • Following Symfony’s quality processes Symfony Cache
  11. #Symfony_Live @nicolasgrekas • Runtime Memory • Filesystem • PHP code

    – one file per item • PHP code – one file with all items • APCu Symfony Cache – Local backends
  12. #Symfony_Live @nicolasgrekas • Redis • Memcached • PDO/DBAL Symfony Cache

    – Remote backends
  13. #Symfony_Live @nicolasgrekas • Chain • Doctrine • Proxy • Null

    • SimpleCache • Traceable Symfony Cache – Special backends
  14. #Symfony_Live @nicolasgrekas Doctrine 834.863 items/ms PHP Cache 313.334 items/ms Stash

    PHP 55.346 items/ms Symfony 533.366 items/ms Symfony Cache – APCu Bench
  15. #Symfony_Live @nicolasgrekas Doctrine 705.001 items/ms PHP Cache 362.477 items/ms Stash

    PHP 153.803 items/ms Symfony 845.910 items/ms Symfony Cache – APCu Bench
  16. #Symfony_Live @nicolasgrekas Doctrine 34.061 items/ms Symfony 478.910 items/ms Symfony Cache

    – Redis Bench
  17. #Symfony_Live @nicolasgrekas • by expiration • by tags • by

    versioning Symfony Cache – Invalidation strategies
  18. #Symfony_Live @nicolasgrekas • igbinary compatibility • MarshallerInterface • Multi-hosts DSN

    Symfony Cache – Extra 4.2 features
  19. Symfony Framework Wiring

  20. #Symfony_Live @nicolasgrekas • cache.system = PHP7 array > APCu >

    files • Offline cache warm-ups for derived cache.validator/serializer/annotations • Fine tuned flex recipes for Doctrine Note: APCu warmup & reset handled properly Best wiring by default
  21. Autowiring FTW! use Psr\Cache\CacheInterface; __construct(CacheInterface $cache) or @cache.app in yaml

  22. #Symfony_Live @nicolasgrekas framework: cache: app: cache.adapter.redis default_redis_provider: 'redis://%env(REDIS_HOST)%' config/packages/framework.yaml

  23. #Symfony_Live @nicolasgrekas framework: cache: pools: forecast.cache: adapter: cache.adapter.pdo config/packages/framework.yaml

  24. @forecast.cache in yaml – 4.2 – CacheInterface $forecastCache

  25. #Symfony_Live @nicolasgrekas Typical Cache Lifecycle

  26. #Symfony_Live @nicolasgrekas Critical Cache Lifecycle

  27. – 4.2 – $cache->get($key, $callback)

  28. #Symfony_Live @nicolasgrekas

  29. #Symfony_Live @nicolasgrekas Cache Stampede at Warm-up

  30. #Symfony_Live @nicolasgrekas Cache Stampede at Warm-up

  31. #Symfony_Live @nicolasgrekas

  32. #Symfony_Live @nicolasgrekas Cache Stampede at Expiration https://en.wikipedia.org/wiki/Cache_stampede

  33. – 4.2 – $cache->get($key, $callback, $beta = null)

  34. #Symfony_Live @nicolasgrekas Get an item?

  35. #Symfony_Live @nicolasgrekas Forcing NO-early expiration

  36. #Symfony_Live @nicolasgrekas FORCING early expiration

  37. #Symfony_Live @nicolasgrekas Deleting an item

  38. $cache->get($key, $callback, $beta = null) – leverages PSR-6 under the

    hood – 99% of use cases covered!
  39. #Symfony_Live @nicolasgrekas Deleting an item

  40. – 4.2 – symfony/contracts

  41. #Symfony_Live @nicolasgrekas • Cache\{CacheInterface, TagAwareInterface} • Translation\TranslatorInterface • Service\{ResetInterface, ServiceLocatorTrait,

    ServiceSubscriberInterface, ServiceSubscriberTrait} • v1.0 released at the end of November • README https://github.com/symfony/contracts Symfony\Contracts\
  42. – 4.2 – use Symfony\Contracts\Cache\CacheInterface; public function __construct(CacheInterface $cache) $cache->get($key,

    $callback, $beta = null) $cache->delete($key)
  43. #Symfony_Live @nicolasgrekas • Offline recomputation (DI+Messenger+Cache integration) • 1RTT Redis

    tag invalidation (joint effort with eZ Platform, they use it the most) What’s next?
  44. None