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
Some hosters have 8MB of limit as their APCU cache limit.
Observation: "Bigger" sites, with a lot of config, especially when its multilingual, pass by this limit. This leads to incredible slow sites, deadlock starts etc.
A couple of APCU related links:
- https://github.com/krakjoe/apcu/issues/86
- https://github.com/krakjoe/apcu/issues/127
Let's try to protect people from running into problems
Proposed resolution
Remaining tasks
User interface changes
API changes
Data model changes
Comment | File | Size | Author |
---|---|---|---|
#70 | Schermafbeelding 2020-02-07 om 09.08.24.png | 62.9 KB | mr.baileys |
#64 | 2800605-apcu-warning-64.patch | 2.79 KB | Chi |
#61 | Screen Shot 2019-11-21 at 12.59.22 PM.png | 45.3 KB | jhedstrom |
#61 | Screen Shot 2019-11-21 at 12.56.59 PM.png | 19.42 KB | jhedstrom |
#59 | 2800605-interdiff-56-59.diff | 1.41 KB | Chi |
Comments
Comment #2
Wim Leers+1 for warning. Drupal 8 is the first version to use a fixed-size cache back-end out of the box. Plenty of people used Memcached with D6 and D7, which was also fixed-size. But that was only for expert-level users, who knew what they're doing. Drupal 8 makes it too easy to shoot yourself in the foot:
Plus this in
\Drupal\Core\Cache\ChainedFastBackendFactory::__construct()
:Together, those mean that we'll default those 3 cache bins to use APCu (chained with DB) automatically. This is problematic as soon as you start having much config (bilingual effectively doubles the amount of config, trilingual triples it, et cetera).
I propose we make
\Drupal\language\LanguageServiceProvider
do slightly more: it's already making container changes based on whether a site is multilingual or not. I propose we also let it changecache.config
'sdefault_backend
service tag.Comment #3
Wim LeersI just discovered the related #2765271: Rationalize use of the 'discovery' cache bin, since it's stored in the limited size APCu by default. Should we do that first?
Comment #4
Wim LeersAlso note that this was introduced in #2248767: Use fast, local cache back-end (APCu, if available) for low-write caches (bootstrap, discovery, and config). We assumed that all sites would have at least the default of 32 MB there.
Comment #5
dawehnerGiven that last comment, I think we should do both. There seems to be no obvious reason, why they could not be done in parallel.
Comment #6
Wim Leers+1
Comment #7
Wim LeersThis code was heavily inspired by how we check the PHP memory limit. The language is equivalent as well.
Comment #8
Wim LeersComment #10
dawehnerI'd had RTBCed that one, but for some reason it doesn't apply.
Comment #11
Wim LeersIt failed because it was rolled against 8.2.x. Now queued that one for testing against 8.2.x.
Attached is a dual reroll: one that's identical to #7 for 8.2.x, and a new patch that applies to 8.3.x. IMHO this should be committed to both 8.2.x and 8.3.x because it's valuable information regardless of version.
Comment #14
Wim LeersTestbot is having a bad day:
… or is this change preventing the installer from completing? I suspect it's that…
Comment #15
dawehnerNote: Warnings block the installer from continuing on
You can disable that by not running the
hook_requirements
on the installer level.Comment #16
Wim LeersThanks for confirming my suspicion in #14. Rerolled with fix.
Comment #17
dawehnerJust a quick sidenote: Does this also means we don't have enough APC memory potentially on the tesbots?
Comment #18
Wim LeersEither testbot doesn't have APCu at all, or it has less than this recommended limit indeed.
Comment #19
dawehnerWell, the patch works for me now.
Comment #20
MixologicThe APCu settings on the testbot environments are as follows:
5.3:
apc.shm_size = 300M
5.5, 5.6, 7:
apc.shm_size = 2000M
Comment #21
dawehnerOh, that's weird, something is wrong with the code then
Oh maybe we are using just APC on 5.5 or so?
Comment #22
Wim LeersBut…
Comment #23
Wim LeersPerhaps testbot has never been testing the APCu cache backend then?
Comment #24
anavarreComment #25
Wim LeersSo, let's debug this. Let's see what testbot really has.
Comment #27
Wim LeersHum. I hacked
run-test.sh
in a way that works locally, but not on testbot apparently.Testbot:
Local:
or
Anybody who knows
run-tests.sh
better who can reroll this?Comment #28
Wim LeersAlso, from the IS:
Opened #2832450: Multilingual config cached in "config" cache bin; quickly reaches APCu memory limits for that.
Comment #29
Wim LeersWith a hint from @alexpott on IRC, I think this may be more successful.
Comment #31
Wim Leersbool(true) + string(5) "2000M"
bool(true) + string(5) "2000M"
bool(true) + string(5) "2000M"
bool(true) + string(5) "2000M"
bool(false) + bool(false)
bool(false) + bool(false)
bool(false) + bool(false)
Conclusion: APCu is not enabled on PHP 7.
Comment #32
MixologicI am so very sorry. When I was looking at the apcu settings I missed that in the actual dockerfile for php7 there is this:
http://cgit.drupalcode.org/drupalci_environments/tree/web/web-7/Dockerfi...
When we launched drupalci, php7 was not yet out, and apcu did not work. This is remnants of that.
we should be addressing a new php7 container soon that includes apcu (and maybe 7.1?)
Comment #33
anavarre@Mixologic is there an issue to follow to know when this will be added to drupalci? Also, I see the todo is referencing 4.0.7 but to my knowledge the minimum version compatible with PHP7 is 5.1.0.
Comment #35
Chi CreditAttribution: Chi commentedDon't we need to negate the condition?
Comment #36
Chi CreditAttribution: Chi commentedRerolled #16 and negated "function_exists" condition.
Comment #37
Chi CreditAttribution: Chi commentedApplied short array syntax.
Comment #38
Chi CreditAttribution: Chi commentedFixed typo.
Comment #39
Chi CreditAttribution: Chi commentedSlightly different approach. It checks available ACPu memory and warns if not much left. The severity is set dynamically.
Comment #43
Wim LeersRetesting, and also testing against PHP 7. That was the problem before.
Let's finish this.
Comment #44
borisson_I'm not sure if this is enough information. I like that this is now dynamic, but I don't like that this removes so much information that was added in the patch Wim had earlier.
It now no longer describes the default memory limit or the reason why that default is no longer sufficient.
We don't usually add links in the actual translatable string, do we?
Should be only one empty line here.
Comment #45
Wim LeersSo are you saying you'd like me to re-upload #16?
Comment #46
borisson_@Wim Leers not sure, I like the fact that there's more granular statuses in #39.
I think the ideal version would be to add the messages used in #16 to #39?
Comment #51
Chi CreditAttribution: Chi commentedOne minor issue we haven't considered yet is that APCu makes no sense in CLI. PHP may have different configurations for a web server and CLI. So that we should not report any warnings when the requirements are checked in CLI context (i.e. via
drush rq
command).Comment #52
Chi CreditAttribution: Chi commentedThe patch brings together #38 and #39.
All php.net links in system_requirements() are hardcoded in translatable strings by some reason. I've used the same approach for consistency.
Comment #53
Chi CreditAttribution: Chi commentedSlightly changed the description as the memory limit was duplicated.
Before:
After:
Comment #54
Chi CreditAttribution: Chi commentedMaybe it's better to return back "Memory usage" description but remove memory limit value in in parentheses.
Comment #55
mr.baileysOverall this looks good to me. However,
Verified on admin/reports/status/php, and there it is listed correctly as 666K:
Specifying the size in Kb is valid according to https://www.php.net/manual/en/apc.configuration.php#ini.apc.shm-size. If I use 16000K as config value, the reported value is correct (15.62Mb). I think this is just a documentation issue, since when debugging this issue on the command line (to determine if this is a PHP bug), I get "PHP Warning: PHP Startup: apc.shm_size now uses M/G suffixes, please update your ini files in Unknown on line 0". Still, the fact that 16000K works and 666K does not might mean this *is* a PHP issue, not just documentation.
In this case, extension_loaded('apcu') will return true (and so does function_exists('apcu_fetch')), so the best option might be to check ini_get('apc.enabled').
Comment #56
Chi CreditAttribution: Chi commented@mrbaileys
Re 1. It also produces weird output for me when using not M/G suffixes.
That line may explain this behavior.
https://github.com/krakjoe/apcu/blob/v5.1.18/php_apc.c#L127
However, the value printed in the status report is taken from apcu_sma_info() which I believe returns a real value.
Re 2. Fixed.
Also added missing warning title when APCu is not enabled.
Comment #57
andypostComment #58
mr.baileysProbably still best to also include a function_exists() or extension_loaded() alongside the ini_get check. For reference, Symfony does:
#2447753: APCu detection erroneously succeeds if apc.enabled is "0" also has a couple of variations on the check for APCu availability.
I think it is preferrable to link to https://php.net instead of http://php.net.
The warning on the status page when APCu is unavalaible looks ok to me:
Comment #59
Chi CreditAttribution: Chi commentedAddressed #58
Comment #60
Chi CreditAttribution: Chi commentedI think we need a ticket to fix all php.net links in Drupal code as we have tons of them.
Comment #61
jhedstromThis looks great to me!
Here are screenshots with the latest patch in #59:
Enabled/default config:
Disabled:
Enabled, low memory:
Comment #63
alexpottMaking this a warning is a bit tricky. There is a situation where this warning could be unresolvable. If you are on a host with no control over your APCu being enabled, or if you can enable it you have no control over the available memory. If this is too small it would make sense to disable APCu and then you've still got a warning. For me this is a recommendation and should be REQUIREMENT_INFO. For me this is the same as using a PHP version which is not supported by PHP but still above the minimum version Drupal supports.
That said it could be argued that this the same opcache which we recommend with a warning. So maybe this is okay.
Comment #64
Chi CreditAttribution: Chi commentedAddressed #63.
Note that current design of status report does not make any visual difference between REQUIREMENT_OK and REQUIREMENT_INFO.
Comment #65
catchCould we convert the actual size to MB too in the requirement message? The screenshot is making people compare 1023.88KB to 32MB.
No strong opinion between info and warning for this one.
Comment #66
dhirendra.mishra CreditAttribution: dhirendra.mishra at Valuebound for Valuebound commentedWorking on this...
Comment #67
dhirendra.mishra CreditAttribution: dhirendra.mishra at Valuebound for Valuebound commentedPlease review my patch as it has fix from comment #65.
Comment #68
mr.baileysI don't think this is going to work, since format_size() can return different sizes:
Your change assumes that format_size is always returning kilobytes. Additionally, the explode/division/concatination feels fragile.
I would actually suggest not altering the patch in #64: in most cases the shm_size will be set using MB (ex. 64 MB), and format_size will report it as 64 MB. It is only when configuring shm_size with non-standard values (such as 123456) that format_size will report with decimal.
Comment #69
Chi CreditAttribution: Chi commented#51 Still needs to be addressed.
Comment #70
mr.baileys@Chi: in #52 you added "
... && PHP_SAPI != 'cli'
" to the if-statement wrapping the requirements check, which seems to do the trick? I am not getting the "No APC SMA info available" warning when runningdrush rq
...apc.shm_size should always be configured in MB or GB. If you use another unit, php issues a warning: "Warning: PHP Startup: apc.shm_size now uses M/G suffixes, please update your ini files in Unknown on line 0". So if configured correctly, you will always see the output on the status screen reported in megabytes (see screenshot). The *only* exception I could find is when apc.shm_size is set to "1M", in which case it is reported as "1023.88 K". I don't think we should accommodate for this edge case, so tentatively setting back to RTBC.
Comment #71
Chi CreditAttribution: Chi commented@mr.baileys, you are right, I tested wrong patch.
Comment #72
Chi CreditAttribution: Chi commentedAnd furthermore the real memory size becomes unpredictable. See notes #55 and #56 for details.
Per #70 the current RTBC patch is in #64.
Comment #73
alexpott@Chi if we commit #64 then we've not addressed @catch's comment in #65 - ah #70 addresses this. I agree a 1mb APCu cache size is an edge case.
Committed and pushed cee0a33481 to 9.0.x and a1f442e6e3 to 8.9.x. Thanks!
Comment #77
colanI just created #3131358: Make APCu requirements errors precise and explanatory , which I believe is a follow-up to this issue.
Comment #78
Chi CreditAttribution: Chi commentedAnother follow-up.
#3142928: Status report wrongly warns of APCu memory limit when admin language is not English
Comment #79
wchaveslive CreditAttribution: wchaveslive as a volunteer commentedIn my experience, after updating Drupal to version 8.9.7 using language in Spanish (if this matter somehow).
The problem was this line:
$apcu_actual_size = $apcu_exploded[0] * 0.001 . ' MB';
I had 32 M dedicated to APC and the variable $apcu_exploded[0] already returns 32; so when the patch 2800605-apcu-warning-67.patch
was trying to multiply by 0.001 it was giving 0.0032 instead of 32 MB which is not much or at least is below the recommended.
I just leave it as:
$apcu_actual_size = $apcu_exploded[0] . ' MB';
create my own patch, apply it and everything works as expected.
Thanks
Walter Chaves
Comment #80
andypost@wchaveslive please use issue from comment above yours to report it - #3142928: Status report wrongly warns of APCu memory limit when admin language is not English
Comment #81
wchaveslive CreditAttribution: wchaveslive as a volunteer and commented