How to use persistent connections with Redis for Symfony Cache with PHP-FPM

How to use persistent connections with Redis for Symfony Cache with PHP-FPMSylvain FabreBlockedUnblockFollowFollowingMay 13In this article, we will learn why using persistent connections is a good practice and how to setup Symfony framework to use persistent connections on a Redis server.

Why use persistent connections?A Redis server is designed to handle a lot of operations per second making it a very good candidate as a data cache storing engine.

But connecting to the server is an expensive operation and thus connections rate should be kept as low as possible.

A solution is to use a proxy like Twemproxy or you may go for persistent connections so they are reused by PHP to serve multiple requests.

Using persistent connections with PHP only works if:you’re using a non-thread safe PHPthe PHP process is not killed once the request has been servedIs my PHP thread safe or not?This is required if you are using phpredis:This feature is not available in threaded versions.

pconnect and popen then work like their non persistent equivalents.

This one is easy to check.

You can use CLI or the phpinfo() method to find out.

This StackOverflow article describe these methods: https://stackoverflow.

com/questions/5799843/find-if-the-installed-php-is-threadsafe-or-nonthreadsafeIs my PHP process killed once the request has been served?This depends on your setup.

Basically, with Apache, you may be using:mod_php (default one):CGIPHP-FPM…PHP-FPM is my favorite one.

With this setup, a pool of PHP processes are started and each process waits for Apache to send requests to handle.

Once the request has been served, then the process waits for another one.

So it’s not killed and thus can use persistent connections to Redis.

How to set SymfonySymfony allows you to easily use Redis as a cache adapter.

You only need to set a Redis DSN as explained in the documentation: https://symfony.

com/doc/current/reference/configuration/framework.

html#default-redis-providerBut this adapter’s default setting uses non-persistent connections as per the default value of persistent according to the documentation: https://symfony.

com/doc/current/components/cache/adapters/redis_adapter.

htmlSo you need to use a custom adapter: https://symfony.

com/doc/current/cache.

html#custom-provider-optionsservices: app.

my_custom_redis_provider: class: Redis factory: [‘SymfonyComponentCacheAdapterRedisAdapter’, ‘createConnection’] arguments: — ‘%env(REDIS_URL)%’ — {persistent: 1, timeout: 15}A 15 seconds timeout is considered to be a good one but you may change it to fit your needs.

Be careful with the 0 timeout as it can create issues (https://github.

com/phpredis/phpredis/issues/1265).

And then create a pool using this provider:framework: cache: pools: cache.

my_redis: adapter: cache.

adapter.

redis provider: app.

my_custom_redis_providerIf you want to use this setup for cache.

app and cache.

system default pools then you need:framework: cache: app: cache.

my_redis system: cache.

my_redisBe careful!Using persistent connections to Redis means that the connection is not closed until the PHP process dies.

So if your PHP-FPM pool creates a lot of PHP processes then theses ones can create more connections than your Redis server is able to handle and this will trigger maximum number of clients reached errors.

.

. More details

Leave a Reply