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

[WP Multisite] Allow flush command to only delete keys for single site #336

Open
JanThiel opened this issue Oct 28, 2021 · 3 comments
Open

Comments

@JanThiel
Copy link
Contributor

Running the wp cache flush Command calls redis flushdb. This clears the complete database.
In a WordPress Multisite environment this call is very expensive as the complete cache for all sites within the network has to be recreated. As the complete Redis DB is flushed. Depending on the size of the network and the required operations to rebuild the cache, this might have severe side effects on all sites. For example using a Multisite Setup with Quota and large amounts of files, the dirsize_cache can take a huge time to rebuild. While the backend of the sites without a cached dirsize_cache is very slow.

I would like to propose and discuss an optimized behaviour:
Flushing the cache in the context of one site should only remove the keys with the prefix of that site, as well as global stored keys. Redis as well as WP-Redis could handle as the key paths are known. Either using prefixes or the hash maps.

This will reduce the flush`s impact to the minimum as well as to the actually requested scope.

Consider this:
wp cache flush --url=site1.com
wp cache flush --url=another-site.com
VS
wp cache flush --network
Currently all three calls will do the same.

I know that this proposal is kind of contrary to the described behaviour here: https://developer.wordpress.org/cli/commands/cache/flush/
But to be honest, the documented behaviour is subpar to what should be an efficient cache management.
What do you think about this?

Or maybe asked from the other way around: How to you handle resetting the cache for a single site only?

Thanks and best,
Jan

@danielbachhuber
Copy link
Contributor

Hey @JanThiel,

I think we need to emulate WordPress core behavior as much as possible, unfortunately. WP Redis needs to act similarly to the other object cache plugins in order to be true drop-in replacement for the WordPress object cache.

Or maybe asked from the other way around: How to you handle resetting the cache for a single site only?

One option would be to connect to a different Redis database depending on which URL was requested. However, this would mean you'd have multiple copies of global cache groups, and modifications to one instance of a global cache group wouldn't be propagated to the other instances.

Another option would be to use native Redis cache groups by define( 'WP_REDIS_USE_CACHE_GROUPS', true );. The blog ID is included in the cache group name, so you could write some custom code to delete all Redis cache groups for a given blog ID. One word of warning is that, when enabled, the expiration value is not respected because expiration on group keys isn't a feature supported by Redis.

If you wanted to write a function and WP-CLI command to clear all groups for a given blog ID when WP_REDIS_USE_CACHE_GROUPS is true, I'd be open to looking at a pull request for that.

@JanThiel
Copy link
Contributor Author

Thanks for your feedback @danielbachhuber!

I was taking chances at the wording in the WordPress docs stating "flushing the object cache will typically flush the cache for all sites".
So I would not rate this as a hard requirement. But something most plugins do because this is the way redis´ flushdb works.

Anyway, I agree that de-facto standards implemented by other object cache implementations have to be in line. So a custom WP-CLI command should and would do the trick.
Let me see what we can do. But that will be something for the gift bringing christmas season. For now we use the following command using redis-cli to do this manually:

redis-cli -a '<REDIS-AUTH>' -n <REDIS-DB-ID> KEYS "<WP-REDIS-SALT-PREFIX><WP-SITE-ID>:*" | xargs redis-cli -a '<REDIS-AUTH>' -n <REDIS-DB-ID> DEL

@danielbachhuber
Copy link
Contributor

Sounds good!

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

No branches or pull requests

2 participants