8000 [Cache] Prevent stampede at warmup using flock() by nicolas-grekas · Pull Request #27604 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Cache] Prevent stampede at warmup using flock() #27604

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jun 18, 2018

Conversation

nicolas-grekas
Copy link
Member
@nicolas-grekas nicolas-grekas commented Jun 14, 2018
Q A
Branch? master
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets -
License MIT
Doc PR -

Replaces #27028

This PR protects against cache stampede by wrapping the computation of items in a pool of locks.

For each apps, there can be at most 20 concurrent processes that compute items at the same time and only one per cache-key.

@nicolas-grekas
Copy link
Member Author

PR ready

@fabpot
Copy link
Member
fabpot commented Jun 18, 2018

Thank you @nicolas-grekas.

@fabpot fabpot merged commit 0ac2777 into symfony:master Jun 18, 2018
fabpot added a commit that referenced this pull request Jun 18, 2018
…las-grekas)

This PR was merged into the 4.2-dev branch.

Discussion
----------

[Cache] Prevent stampede at warmup using flock()

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | -
| License       | MIT
| Doc PR        | -

Replaces #27028

This PR protects against cache stampede by wrapping the computation of items in a pool of locks.

For each apps, there can be at most 20 concurrent processes that compute items at the same time and only one per cache-key.

Commits
-------

0ac2777 [Cache] Prevent stampede at warmup using flock()
@nicolas-grekas nicolas-grekas deleted the cache-flock branch June 18, 2018 16:13
@pounard
Copy link
Contributor
pounard commented Jun 25, 2018

I spent a few hours reviewing most of your performance changes, I have been impressed by most of it (the probabilistic early expiration is a very nice feature to have, although I don't like the way you implemented it because it does very heavy magic relying a bit too much on PHP internals for my taste, but that's details, and I won't fight over details because you did a great job) although, reviewing this one, there are a few points worrying me:

  • are you not afraid using flock() ? I mean, it's efficient and working well as long as you are on a fast local harddrive, but I'm worried that working on a NFS tailored for fast reads, with the cache that goes with it, might yield some very bad side effects especially when you temporary loose sync (it happens very often),
  • you documented in [Cache] Add stampede protection via probabilistic early expiration #27009 that the new CacheInterface is the way to go, without any further precisions, but it does not document that now, it also hardcodes flock() calls (there is no way to work around this except by doing an eary setFiles([]) call, which is undocumented),
  • this is all set by default with no option to deactivate it, I especially dislike this, it should be something that sysadmins must be in capacity to deactivate or tune depending on their environment without the need of having a very experienced developer able to write a custom wrapper or a patch around.

Besides, I can see were it could cause trouble, a simple example from my mind (but I might be wrong so please correct me if there's something I missed) but what happens if I use a bundle that uses the new CacheInterface to store business cache items (not system cache here) let's say in a shared Redis instance, and I have a certain number of web heads with each of them their own local filesytem, wouldn't that mean that eventually it would trigger the LockRegistry usage, were in that case it seems highly unnecessary ?

I had thought the last few hours about a couple of other uses cases were it could go wrong, or just be useless, but I don't remember them all.

Don't take it wrong, what you did here is a good move toward stampede protection, I'm just very worried that the flock() usage is hardcoded, and there's no easy way to deactivate or implement another way than by decorating or overriding services.

@pounard
Copy link
Contributor
pounard commented Jun 25, 2018

Moreover, as a side note, it seems that ArrayAdapter and NullAdapter don't need the GetTrait at all, they would function properly with a more straight foward implementation without the the stampede protection as they are meant to live into memory only for the request.

@nicolas-grekas
Copy link
Member Author

Hi @pounard thanks for your comments, that's great to know some care and noticed :) Can you open an issue so we can discuss this? I'd be happy to further improve.

@pounard
Copy link
Contributor
pounard commented Jun 25, 2018

@nicolas-grekas thanks for you for answering so fast ! I will open an issue with pleasure, I'll try to do a more structured write up to start with, I will within the week (tomorow or the day after). Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants
0