Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
APCU seems to be designed around the idea to store many small entries. On the other hand Drupal stores cache.discovery in there
, which has a lot of big entries.
@dawehner has seen deadlocks on some sites which got bigger. https://github.com/krakjoe/apcu/issues/127#issuecomment-155433811 also reports general problems with big cache entires and many small ones, see screenshot:
Per default APCU has 257 slots for data, so maximum for example 32MB/257 in size per slot, aka 125KB max, which exceeds the view cache example above.
Proposed resolution
Maybe remove the big entries and move it to normal cache?
Remaining tasks
User interface changes
API changes
Data model changes
Comment | File | Size | Author |
---|---|---|---|
#24 | apcu_usage.php_.txt | 1.76 KB | Wim Leers |
#6 | 2765271-6.patch | 1.2 KB | Wim Leers |
Screen Shot 2016-07-13 at 10.41.26.png | 584.57 KB | dawehner |
Comments
Comment #2
dawehnerComment #4
Wim LeersComment #5
Wim LeersNote that this was introduced in #2248767: Use fast, local cache back-end (APCu, if available) for low-write caches (bootstrap, discovery, and config). We weren't aware then of problems with big cache entries.
This is very interesting. http://php.net/manual/en/apc.configuration.php lists 4096 as the default.
Comment #6
Wim LeersI think the patch can be this simple.
But I think we need profiling to understand the impact of this before it can be committed.
Comment #7
BerdirYes, definitely. Another option would be to get specific big cache entries out of the bin. config and discovery both have possibly very large amount of cache gets, and config can actually grow a lot too, if you have a lot of config.
Will try to collect some numbers from some of our bigger sites.
Comment #9
catch@dawehner did a blog post here which explains the 257 a bit more: http://dawehner.github.io/php/2016/07/13/osx-apc.html
On the patch itself, this bit is unnecessary:
The container gets rebuilt by core version number increments, no need for an update.
This potentially affects #2704571: Add an APCu classloader with a single entry too not just cache.discovery - would be good to know if it's an issue just with size or also with number, since that'd cut down the number a lot, but won't be small.
One way to approach this would be to gzip compress cache entries over a certain size (i.e. strlen() then compress with a flag to say it's compressed), but that's adding some complexity.
Comment #10
Wim Leershttp://dawehner.github.io/php/2016/07/13/osx-apc.html is gold. Thanks.
I'm willing to bet 99% of people don't know about this "257 slots" thing.
Comment #12
dawehnerI need to follow up on that one and maybe see whether more recent versions of APCU fixed some of the locking problems. There has been also alternative caches out there.
Comment #13
BerdirLooked at one of our projects.
In total, I have 400 entries in the discovery bin pretty recently after a cache clear, on production in redis I see 440. the config cache bin on the other hand has 6k entries. So config is actually a bigger problem as far as number of entries goes.
The problem with discovery is that some entries can get pretty big. views_data is obviously a clear winner there. I thought I've opened an issue for that already but apparently not. Especially since views_data is something that you should *not* need at runtime, only when caches are built and in the backend. We could have two backends but the number of cache requests is likely fairly low.
token_info is already bug, this is because token.module now exposes tons of tokens for fields and properties by default.
From then on, it is mostly entity definitions and a few bigger plugin caches. We could move some of that too. But I think keeping most of the plugin definitions like all the views stuff in discovery and that in apcu would be beneficial.
Edit, formatting doesn't work well it seems, better readable version: https://gist.github.com/Berdir/584a23ddd3169bccfb6c220d14b32018
Comment #14
Wim LeersYep, exactly. This is also the analysis dawehner made in the IS.
So you are proposing to move all the
views_data:*
cache items out of thediscovery
cache bin, into a separate cache bin. Possibly just use thedata
cache bin?Comment #15
dawehnerWe have two kind of cache entries in there:
Comment #16
catchMoving the main views data entry out is great.
I really doubt we need token in there either - most requests are not rendering tokens.
Should we open sub-issues to move those out and maybe make this a meta to rationalise what goes in there? That seems preferable to dropping chained_fast unless there's an insurmountable issue with apcu.
After that entity_field_map, typed_config_definitions and typed_data_types_plugins all look borderline, we need to look at where they get requested.
Comment #17
Wim Leers+1
Comment #18
BerdirCreated #2824547: Change ViewsData to use the default cache bin instead of discovery and #2824548: Move token info cache to data cache bin
Comment #19
Wim LeersBoth #2824547: Change ViewsData to use the default cache bin instead of discovery and #2824548: Move token info cache to data cache bin have landed! Both have been committed to 8.3.x only. Berdir's profiling at #2824548-4: Move token info cache to data cache bin looks very encouraging:
Those two issues having been committed will reduce the chance of APCu errors on 8.3.x sites. But that doesn't help current production sites… so what about those?
Should we create a CR, to inform site owners of this change? It would only cause a very small percentage of site owners to look into things, but still, it's probably worth calling out.
From #16:
This is now done.
What do we want to do with those?
Comment #20
anavarreComment #21
Wim LeersOpened #2832450: Multilingual config cached in "config" cache bin; quickly reaches APCu memory limits as the next step here.
Comment #24
Wim Leers@msonnabaum did some testing back in December 2016, before Drupal 8.3 was released. He wrote a script (attached).
I figured this would be a valuable data point here to continue this issue. It confirms the need for #2832450: Multilingual config cached in "config" cache bin; quickly reaches APCu memory limits.
Comment #25
geek-merlinGzipping data effectively saves 80% size with minimal CPU cost. We use this compressed backend in redis successfully for quite some months. See
* Redis #2826332-2: Option to compress data
* Core #1281408: Add a compressing serializer decorator