Skip to content
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

Not possible to disable memcache, causing slow page loads #84

Open
maskedjellybean opened this issue Feb 29, 2024 · 8 comments
Open

Not possible to disable memcache, causing slow page loads #84

maskedjellybean opened this issue Feb 29, 2024 · 8 comments
Labels
bug Something isn't working

Comments

@maskedjellybean
Copy link

Even if you have cache set to false in .lando.yml (as documented here: https://docs.lando.dev/plugins/acquia/config.html), and do not have a Drupal memcache module installed (disabled for local development environment using config_split Drupal module), memcache related code will run on every page load, causing significant slowness.

While investigating why my site was so slow, I found this issue:
#10

A user there pointed out something extremely problematic for anyone who does not have the Drupal memcache module enabled and configured and does not want to. The issue is caused by the interplay of Lando setting $_ENV['AH_SITE_ENVIRONMENT'] to "LANDO", and the memcache related code in the Acquia created/controlled docroot/sites/default/settings/cloud-memcache-d8.php file.

In cloud-memcache-d8.php, this if statement will ALWAYS be true:

/**
 * Use memcache as cache backend.
 *
 * Autoload memcache classes and service container in case module is not
 * installed. Avoids the need to patch core and allows for overriding the
 * default backend when installing Drupal.
 *
 * @see https://www.drupal.org/node/2766509
 */
if (array_key_exists('memcache', $settings) &&
  array_key_exists('servers', $settings['memcache']) &&
  !empty($settings['memcache']['servers'])
) {

This is because Lando sets the $_ENV['AH_SITE_ENVIRONMENT'] variable, and Acquia creates the $settings['memcache'] array in another Acquia settings file.

Initially I thought I could unset the array in my local.settings.php, but this is not possible, because local.settings.php is ran AFTER cloud-memcache-d8.php.

The only way I have found to avoid this if statement being true is to unset $_ENV['AH_SITE_ENVIRONMENT'] in .lando.yml:

services:
  appserver:
    overrides:
      environment:
        AH_SITE_ENVIRONMENT:

This likely has side effects, or else Lando wouldn't bother to set the variable in the first place. However, after adding that and running lando rebuild, my site is significantly faster. Using Xdebug, I can confirm that the if statement in cloud-memcache-d8.php evaluates to false and the memcache code does not run.

Can we find a way to actually disable memcache that plays nicely with Acquia files that we have no control over?

@maskedjellybean maskedjellybean added the bug Something isn't working label Feb 29, 2024
@reynoldsalec
Copy link
Sponsor Member

Does Acquia allow disabling of memcache on Acquia Cloud?

Mostly want to understand the use case for setting cache: false to try and figure out the best way for Lando to accomodate it.

@maskedjellybean
Copy link
Author

Thanks for the response. No I don't think Acquia Cloud allows disabling memcache. I do see your point, but IMO the Lando Acquia plugin offers the ability to disable the memcache server and documents it, so I think it should work. Otherwise I think the option should be removed.

This is maybe too in the weeds and I don't want to distract from the actual issue, but my personal reason for not wanting memcache is that I'm adding Lando as a local development option to a project that traditionally runs on a custom vanilla Docker setup. That setup has never used memcache locally. It's disabled by the local Drupal config split. Because Lando and the original setup share Drupal config, if I were to enable the memcache module in the config split, it would be enabled for the the original setup as well. I don't want to figure out how to run a memcache server for the original setup (or deal with pushback from the dev in charge of the original setup).

@maskedjellybean
Copy link
Author

maskedjellybean commented Feb 29, 2024

Based on my experience and that other issue I linked, there's people using the Lando Acquia plugin who are using memcache because they think it's the only way to make Lando fast. But in fact the slowness is not inherent in Lando, it's caused by all this code accidentally running.

@reynoldsalec
Copy link
Sponsor Member

For your project @maskedjellybean, would it just make more sense to not use the Acquia recipe?

I thought folks who are on Acquia Cloud would have memcache set up on their Drupal site, and that the Lando Acquia plugin logic should change the settings correctly to make that work (that was the PR associated with the previous issue).

Don't know what order the settings.php files load in, but would be interesting to try and unset($settings['memcache']) in acquia-settings.inc...might be able to override the Acquia logic that way if we want to go down that road.

@maskedjellybean
Copy link
Author

maskedjellybean commented Feb 29, 2024

I am using the Acquia recipe/plugin, which is why I created the issue here, but again I understand that it would make the most sense to just use memcache. EDIT: Sorry, I misread your question. The only thing that I don't want from the Acquia plugin is memcache, and theoretically that is optional, so it still makes the most sense to use the plugin.

Unfortunately I don't know the best way to resolve this from a Lando perspective. Assuming acquia-settings.inc were loaded after whichever Acquia settings file sets $settings['memcache'], but before cloud-memcache-d8.php, could acquia-settings.inc be modified based on whether cache is true in .lando.yml?

@AaronFeledy
Copy link

AaronFeledy commented Mar 19, 2024

This issue isn't about Lando specifically, but more about understanding how Drupal's Memcache module works. The Memcache module speeds up cache access by storing Drupal's cache in memory instead of the database. However, during its startup, Drupal reads from the database cache to know which modules to load, each of which also may use the cache. Simply pointing cache to memory via a module doesn't help much if the database cache is still heavily used before accessing the memory cache. To fully benefit from Memcached, it's essential to load the Memcache module as early as possible, bypassing the standard module loading. This is done by manually loading the module's files in the settings.php file, which loads early in Drupal's startup. Acquia provides a similar setup with the cloud-memcache-d8.php file, which they had you call in your settings.php. This way, the module runs early, enabling the cache even before Drupal checks which modules are enabled.

Lando aims to mirror the Acquia environment, including the use of the AH_SITE_ENVIRONMENT variable, which helps differentiate between development, test, and production environments. Lando introduces a "lando" value for this variable, acting as a fourth environment type. This is ideal for sites that are reliant on various services that are present on Acquia.

The issue arises when memcached is hard-coded enabled for Acquia environments but the memcached server isn't running in the "LANDO" Acquia environment. To address this, you could remove the AH_SITE_ENVIRONMENT variable, but this might reduce the accuracy of replicating Acquia's environment and potentially break certain features of the site. Alternatively, adjusting your settings.php to conditionally load memcache configurations based on the environment can prevent forcing a connection to memcache when it's unavailable.

Here's an example of how to conditionally configure memcache in the settings.php:

if (!empty($_ENV['AH_SITE_ENVIRONMENT']) && $_ENV['AH_SITE_ENVIRONMENT'] != 'LANDO') {
  // Cache settings
  $settings['memcache']['servers'] = ['cache:11211' => 'default'];
  $settings['cache']['default'] = 'cache.backend.memcache';';
  $settings['cache']['bins']['bootstrap'] = 'cache.backend.memcache';
  ...
  
  // Load memcache config for Acquia environments
  if (file_exists(DRUPAL_ROOT . '/sites/default/cloud-memcache-d8.php')) {
    require(DRUPAL_ROOT . '/sites/default/cloud-memcache-d8.php');
  }
}

For personal setups, you could leave the settings.php as-is and instead adjust settings.local.php to revert cache bins back to the database cache. The early loading of the Memcache module and Acquia config will be rendered inconsequential if Drupal never actually tries to access the memcache caches:

$settings['cache']['default'] = 'cache.backend.database';
$settings['cache']['bins']['discovery'] = 'cache.backend.database';
$settings['cache']['bins']['bootstrap'] = 'cache.backend.database';
$settings['cache']['bins']['render'] = 'cache.backend.database';
$settings['cache']['bins']['data'] = 'cache.backend.database';
$settings['cache']['bins']['config'] = 'cache.backend.database';

Tip: If you're working on something that requires you to clear the cache a lot, you can disable one or more of the caches by setting the bin to cache.backend.null instead of pointing it to the database.

@maskedjellybean
Copy link
Author

The thing I'm getting at is that the Lando Acquia documentation says that you can disable the Memcache server via .lando.yml (https://docs.lando.dev/plugins/acquia/config.html#customizing-the-stack) with cache: true. This is technically correct, but if you do this it will leave you in the situation I described. My concern is that a lot of people won't know how to resolve the slow page load times they're experiencing. This is a Lando specific issue. If Lando didn't pretend to be an Acquia environment by setting the AH_SITE_ENVIRONMENT variable, there would be no problem. If you host an Acquia site locally in any way other than Lando, the variable won't be set, and you won't run into this problem. I realize that this is not an easy issue to solve because there are probably other reasons Lando sets the variable (although I haven't found anything that doesn't work with the variable unset). If it's out of the control of Lando, I think it could be solved via documentation. I would recommend either removing the cache: false line from the documentation or adding a note with a link to this issue. Not trying to be difficult, only trying to help the next person.

@reynoldsalec
Copy link
Sponsor Member

For sure, appreciate your commitment to the issue @maskedjellybean!

I'm thinking that maybe a note in the config docs linking to a Guide that details @AaronFeledy's settings.php config would be appropriate, IE:

if (!empty($_ENV['AH_SITE_ENVIRONMENT']) && $_ENV['AH_SITE_ENVIRONMENT'] != 'LANDO') {
  // Cache settings
  $settings['memcache']['servers'] = ['cache:11211' => 'default'];
  $settings['cache']['default'] = 'cache.backend.memcache';';
  $settings['cache']['bins']['bootstrap'] = 'cache.backend.memcache';
  ...
  
  // Load memcache config for Acquia environments
  if (file_exists(DRUPAL_ROOT . '/sites/default/cloud-memcache-d8.php')) {
    require(DRUPAL_ROOT . '/sites/default/cloud-memcache-d8.php');
  }
}

@maskedjellybean does that sound good? Would definitely appreciate help if you're interested in putting up a PR for it; you've probably seen the relevant Config docs, and adding a Guide just involves adding another page to this directory (I suggest copying one of the other guides and editing that format to make sure you get the correct frontmatter).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants