Open ejunker opened 5 years ago
Stash allows developers to handle stampedes in a number of ways-
My recommendation is to either expose the options to developers so they can pick, or go with option number two and attempt to recalculate before the expiration time actually hits.
Also, don't underestimate how big of a deal this is- when one of my former clients (one of the top five adult sites in the US) switched to the precompute method they were able to drop the number of servers their search service was using by 20%. The dogpile/stampede issues can be a huge performance loss.
Just discovered that Symfony has cache stampede protection https://symfony.com/doc/current/components/cache.html and it looks like it now uses "Probabilistic early expiration" by default.
They use probabilistic early expiration (option two above), but they also implement locking by default as well-
The first solution is to use locking: only allow one PHP process (on a per-host basis) to compute a specific key at a time. Locking is built-in by default, so you don't need to do anything beyond leveraging the Cache Contracts.
Their documentation doesn't make it clear how they respond to locks though, and I imagine with the precompute option it's not something they run into regularly anyways.
They wrote the blog post about it https://symfony.com/blog/new-in-symfony-4-2-cache-stampede-protection
I wouldnt make this a default behavior, but rather an extra option. Maybe as a proxy/decorator driver. Then you could have all options above as separate proxies.
Would love to have this built in into the framework
When a cache key expires you may run into a situation where there are multiple requests for a cache key which causes multiple processes to try to calculate the cache value. This is commonly referred to as a "stampede". I noticed that other cache implementations have stampede protection and I think it would be a good addition to Laravel. I was primarily thinking
Cache::remember()
could somehow place a lock or mutex while the closure is running and respond with stale data if it is available or wait until the closure finishes running and has the result. Maybe\Illuminate\Cache\Lock
could be used.https://blog.tedivm.com/rants/2014/10/a-walkthrough-of-psr-6-caching/
https://github.com/matthiasmullie/scrapbook/blob/master/src/Scale/StampedeProtector.php