Search code examples
symfonyredissymfony4

Symfony RedisAdapter has different internal cache keys depending on app environment


I am using a redis cache in my symfony application.

When inspecting the internally used keys in redis-cli I found out that all entries share a common prefix (like AWVAugkC6-:, or gBphwvED1G:). The prefix changes if I toggle APP_ENV between dev and prod.

Can I disable this behavior?

Currently, I cannot use the prod entries in dev mode, and vice versa.

A call to

$this->cache->getItem('2f560421-1b6d-4251-8392-e9c0f5e824a7-1514764800-1546300799-noref-nostr');

translates in devmode to a redis key

gBphwvED1G:2f560421-1b6d-4251-8392-e9c0f5e824a7-1514764800-1546300799-noref-nostr

however in prod, it's

AWVAugkC6-:2f560421-1b6d-4251-8392-e9c0f5e824a7-1514764800-1546300799-noref-nostr

So the prefix is exchanged!

I have traced this back to AbstractTrait::getId($key) https://github.com/symfony/cache/blob/e5e9a6d35558b43cca49cde9f3a7ad22980812cb/Traits/AbstractTrait.php#L269, but I think this line should just hash the give key, not the environment...?

framework:
    cache:
        default_redis_provider: 'redis://%env(REDIS_HOST)%'
        pools:
            data_evaluator_cache_items_cache:
                adapter: cache.adapter.redis
                default_lifetime: 0
                public: true
            data_evaluator_cache_tags_cache:
                adapter: cache.adapter.redis
                default_lifetime: 0
                public: true 
services:
    tagged_data_cache:
        class: Symfony\Component\Cache\Adapter\TagAwareAdapter
            arguments:
                $itemsPool: "@data_evaluator_cache_items_cache"
                $tagsPool: "@data_evaluator_cache_tags_cache"
        public: true

I am unsure if this relates to the TagAwareAdapter. In reality an additional tag entry is stored, which


Solution

  • The prefix is computed to ensure dev and prod don't share the same cached items, to be safe by default. This is done when using semantic configuration, in a compiler pass, here:

    https://github.com/symfony/cache/blob/master/DependencyInjection/CachePoolPass.php#L55

    If you want to opt out from this, you might need to define your cache pools directly as a service - without using semantic configuration. You'll then have full control over the namespace and everything else.

    You can also keep using semantic and redefine the kernel.container_class parameter. I think this can be done by overriding the getContainerClass on your Kernel.

    But you should double check first why you need same namespace for prod and dev.