How to share the application cache between multiple Symfony instances (shared cache pool)?
Asked Answered
T

2

5

My symfony application has multiple instances that are running in seperate docker containers.

And I have configured my app.cache to use redis:

framework:
    cache:
        app: cache.adapter.redis

I have the same prefix_seed:

framework:
    cache:
        prefix_seed: 'dev'

As a result I'm getting in redis something like this:

1605259288.470950 [0 172.18.0.28:55044] "MGET" "HnMEIyUlZ+:workers.restart_requested_timestamp"
1605259288.471680 [0 172.18.0.28:55044] "SET" "HnMEIyUlZ+:workers.restart_requested_timestamp" "d:1605259288.471522;"
1605259314.483389 [0 172.18.0.29:42884] "MGET" "8TMgMtnOAG:workers.restart_requested_timestamp"

As you can see from the above 2 different instances are trying to fetch value from redis by the same key workers.restart_requested_timestamp but the prefix is different even with the same prefix_seed.

In this example I'm using messenger component, and I want to stop workers running everywhere by stop-workers command (through the shared redis). But generally speaking this is related to cache configuration.

How to overcome this and tell both applications to use same pool? What is the configuration for this?

Towhaired answered 13/11, 2020 at 9:6 Comment(3)
@yivi I found that it won't work as expectedTowhaired
Check this out. It might help you.Tuneless
Does this answer your question? Set Redis cache prefix key on SymfonyVeedis
T
7

Finally, I found the solution. There's an option to create your own cache pool with mapped adapter to it. The main trick here is to pass the tag with namespace to your adapter (name is also should be cache.pool):

framework:
    cache:
        pools:
            cache.redis_shared_pool:
                adapter: app.cache_shared_redis_adapter

services:
    app.cache_shared_redis_adapter:
        parent: 'cache.adapter.redis'
        tags:
            - { name: 'cache.pool', namespace: 'shared' }

That's it! All your keys in redis will be prefixed with shared:. Now you should pass your @cache.redis_shared_pool to any service you want.

And as for the messenger component, we should override the services (but I'm not sure this is the best way):

console.command.messenger_stop_workers:
    class: Symfony\Component\Messenger\Command\StopWorkersCommand
    arguments:
       $restartSignalCachePool: "@cache.redis_shared_pool"

messenger.listener.stop_worker_on_restart_signal_listener:
    class: Symfony\Component\Messenger\EventListener\StopWorkerOnRestartSignalListener
    arguments:
       $cachePool: "@cache.redis_shared_pool"
Towhaired answered 16/11, 2020 at 7:10 Comment(1)
If you are using auto-wiring you can use CacheInterface $cacheSharedPool where the variable is the name of the pool in CamelCase. Symfony automatically creates those auto-wire service IDs from your pool names. I'm not sure you can use pools with periods in the name however.Swatow
B
0

In the symfony framework bundle's configuration definition you could find:

    private function addCacheSection(ArrayNodeDefinition $rootNode)
    {
        $rootNode
            ->children()
                ->arrayNode('cache')
                    ->info('Cache configuration')
                    ->addDefaultsIfNotSet()
                    ->fixXmlConfig('pool')
                    ->children()
                        ->scalarNode('prefix_seed')
                            ->info('Used to namespace cache keys when using several apps with the same shared backend')
                            ->example('my-application-name')
                        ->end()
                        ...

prefix_seed is exactly what you are looking for. Check the documentation here: https://symfony.com/doc/current/reference/configuration/framework.html#prefix-seed

Bombastic answered 13/11, 2020 at 9:56 Comment(2)
I have the same prefix_seed everywhere, in my case it depends from the environment and build id: prefix_seed: '%env(APP_ENV)%_%env(BUILD_ID)%'Towhaired
But if you try to run the same symfony application in 2 independent containers you will find that the prefix will be different.Towhaired

© 2022 - 2024 — McMap. All rights reserved.