Skip to content

[Cache] TagAwareAdapter and LockRegistry possibly causing deadlocks #59191

Open
@dakujem

Description

@dakujem

Symfony version(s) affected

5.4.46

Description

Hello everyone!

We just ran into server issues leading to deadlocking php-fpm processes leading to server crash. We pinned it down to the Symfony\Component\Cache\LockRegistry calling flock ...

As a hotfix solution we disabled the cache stampede prevention feature.

Now, I assume we are doing something wrong. I came here to confirm this and/or get some pointers or insight into the matter. I posted this first to the Slack support channel, but was redirected here by Nicolas.

Also, I understand that we are using legacy version of symfony/cache component on legacy PHP project. But I did check and compare the code diff of LockRegistry between 5.4.46 and the most recent 7.3 version, and found no relevant changes to the algorithm, only syntactic sugar changes for PHP 8, and a single file removed from the $files list.

What our configuration looked like before the deadlocks is in this screenshot.
The key thing to note is that we are wrapping the redis/memcached/whatever adapter is currently in use with TagAwareAdapter adapter to support tag-based invalidation.
image

After the crashes and investigation we added calls to $adapter->setCallbackWrapper(null) to inhibit the stampede prevention on both adapters:
the redis/memcached adapter and the wrapping TagAwareAdapter.
image

I made an assumption (a guess really), that the deadlock occurred because the stampede prevention algorithm kicked in in both the adapters. We should be able to enable the prevention on the outer adapter (TagAwareAdapter) without encountering the deadlock again.
I made the assumption because I did not find other people complaining about deadlocking cache at any relevant websites.

My question is this:
Were we supposed to disable the stampede prevention on the inner adapter in the first place? If so, I suggest this case be documented.
Otherwise, what can we do to prevent the stampede prevention from crashing our server, if we do not want to disable it completely?

I think that only disabling the stampede prevention on the adapter being wrapped might be sufficient, but I do not want to cause the crashes anymore, it took considetable effort to pin the issue down.
image
So I came for a couple of pointers.

Thanks anyone for an insight in advance!

How to reproduce

new TagAwareAdapter(new RedisAdapter($redisClient))

At the moment we are using both Memcached and Redis, I'm aware there is RedisTagAwareAdapter too, but we chose the above configuration.

How does one reproduce a deadlock? I have no idea here.

Possible Solution

No response

Additional Context

My main question is this:

Are we supposed to disable the stampede prevention on the inner adapter when wrapping it with TagAwareAdapter?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions