Code Monkey home page Code Monkey logo

wp-memcached's Introduction

=== Memcached Object Cache ===
Contributors: ryan, sivel, andy, nacin, barry, ethitter, nickdaugherty, batmoo, simonwheatley, jenkoian, bor0, aidvu
Tags: cache, memcached
Requires at least: 5.3
Tested up to: 6.0
Stable tag: 4.0.0
Requires PHP: 7.4.0

Use memcached and the PECL memcache extension to provide a backing store for the WordPress object cache.

== Description ==
Memcached Object Cache provides a persistent backend for the WordPress object cache. A memcached server and the PECL memcache extension are required.

== Installation ==
1. Install [memcached](http://danga.com/memcached) on at least one server. Note the connection info. The default is `127.0.0.1:11211`.

1. Install the [PECL memcache extension](http://pecl.php.net/package/memcache)

1. Copy object-cache.php to wp-content

1. Add the `WP_CACHE_KEY_SALT` constant to the `wp-config.php`:

```php
define( 'WP_CACHE_KEY_SALT', '...long random string...' );
```

This helps prevent cache pollution when multiplte WordPress installs are using the same Memcached server. The value must be unique for each WordPress install.

== Frequently Asked Questions ==

= How can I manually specify the memcached server(s)? =

Add something similar to the following to wp-config.php above `/* That's all, stop editing! Happy blogging. */`:

`
$memcached_servers = array(
	'default' => array(
		'10.10.10.20:11211',
		'10.10.10.30:11211'
	)
);
`

The top level array keys, are cache groups, where 'default' corresponds to any cache group that is not explicitly defined. This allows for specifying memcached servers that only handle certain cache groups. The most common use is only specifying 'default'.

Possible cache groups are:

`
{$taxonomy}_relationships
{$meta_type}_meta
{$taxonomy}_relationships
blog-details
blog-id-cache
blog-lookup
bookmark
calendar
category
comment
counts
general
global-posts
options
plugins
post_ancestors
post_meta
posts
rss
site-lookup
site-options
site-transient
terms
themes
timeinfo
transient
user_meta
useremail
userlogins
usermeta
users
userslugs
widget
`

== Changelog ==

= 4.0.0 =
* Add preemptive filter pre_wp_cache_get
* Add flush_number replication to prevent accidental flush due to flush_number eviction, server rotation, etc.

= 3.2.2 =
* Remove filter, and base key stripping on presence of `key_salt`

= 3.2.1 =
* Fix bug allowing **slow-ops** entries to have the same key, so toggling doesn't work

= 3.2.0 =
* Better stats(). Now shows cache group/individual calls with size of the payload and timings.
* PHP 5.6.20 is now required
* Fix **get_multi** to show per group calls
* Added filter **(memcached_strip_keys)** to bypass memcached key stripping
* Special group for **slow-ops** ( > 5ms ) with backtrace

= 3.1.0 =
* Add **wp_cache_get_multi**
* Add support for the **$found** parameter
* Set a variable for $max_expiration to 30 days
* Code style changes
* Different coloring for unknown stats group
* Store host/port on failure_callback
* Default stats counts

= 3.0.2 =
* Better output of HTML

= 3.0.1 =
* Fix key generation error in switch_to_blog()

= 3.0.0 =
* Flush site cache by rotating keys
* Flush global cache when flushing main site

= 2.0.6 =
* Flush the local cache on wp_cache_flush()

= 2.0.5 =
* Fix missing global in switch_to_blog

= 2.0.4 =
* Remove deprecated constructor

= 2.0.3 =
* Support for unix sockets

= 2.0.2 =
* Break references by cloning objects
* Keep local cache in sync with memcached when using incr and decr
* Handle limited environments where is_multisite() is not defined
* Fix setting and getting 0
* PHP 5.2.4 is now required
* Use the WP_CACHE_KEY_SALT constant if available to guarantee uniqueness of keys

wp-memcached's People

Contributors

aidvu avatar bor0 avatar dd32 avatar dependabot[bot] avatar ethitter avatar garyjones avatar joshbetz avatar mjangda avatar nickdaugherty avatar paulschreiber avatar rebeccahum avatar simonwheatley avatar sjinks avatar skeltoac avatar spacedmonkey avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wp-memcached's Issues

Undefined index notice when stats get reset

Various systems reset the stats array to an empty array, which deletes all of the keys, such as 'get' and 'add'. Common examples include:

This was recently fixed in the VIP WP CLI helper: Automattic/vip-go-mu-plugins@515b71d

Since the property is public and we can't control for every use case, one thing we can do is to ensure that the increments are happening safely, rather than assuming the property exists, as is done here: https://github.com/Automattic/wp-memcached/blob/master/object-cache.php#L319

Widgets - data loss

Have you had any reports of data loss concerning widgets? We have had two sites in quick succession report issues where sections of widgets under Appearance->Widgets have been apparently deleted. I can confirm this was not user error. We have deactivated Memcache as a precaution.

We are on the latest version 4.0.0 and Wordpress 5.8.1. We also run HyperDB v1.7.

Bug with transient API

Hello,
We used wp memcached successfully on a customer website, but recently we had to disable it because a specific plugin did not work correctly, more info here (french) : https://wordpress.org/support/topic/le-paiement-oney-ne-fonctionne-plus/

The specific plugin relies on transients and apparently when we enable object caching transients are not reliable anymore.

The plugin author recommended us to switch to WP Rocket (sic) in which there is an option not to cleanup transients in database, which apparently fixes the problem.

Does anybody knows if there is such a possibility for wp memcached ? Or maybe we could add some filters to exclude this plugin from object cache ?

Thank you for your help :)
Mathieu.

does this thing have a license?

Hey I'd like to fork this for my own needs but would feel better if there was a license attached. I was surprised to find code in Automattic/ without one.

I am assuming GPL2 since it's derived-ish(?) from core wordpress but I'd love a clarification.

PHP 8.2 compatibility?

Hi,

I have noticed some deprecations in PHP 8.2. Will the object cache class be updated soon to be compatible with PHP 8.2?

Best regards,
Himanshu

It doesn't work with unix sockets

It works OK when I configure Memcached to use a TCP connection (listening on 127.0.0.1 on port 11211), but it doesn't work when I configure Memcached to use unix sockets, which would allow higher speeds, although 'object-cache.php' supports unix sockets.

To make Memcached use a unix socket instead of a TCP connection, in the /etc/memcached.conf file, I commented out the port and IP address lines and added the socket and permissions lines, like this:

#-p 11211
#-l 127.0.0.1

-s /var/run/memcached/memcached.sock
-a 775

Also, I added the following lines to the wp-config.php file of the WordPress website:

$memcached_servers = array( 'default' => array(
        'unix://var/run/memcached/memcached.sock')
);

I restarted Memcached and indeed, memcached.sock was created in the '/var/run/memcached directory which was owned by the memcache user, but all the webpages became very slow. They loaded, but very slowly. When I returned to TCP connections it worked again and I could see that Memcached stored data in RAM. I experimented with different permissions for the socket file, so as to give www-data read access to it, but in vain.

What can be wrong ?

I'm using Debian 10, Nginx 1.14.2, WordPress 5.4.2.

Confusing installation

Hello

The installation instructions are a bit confusing.

I've copied object-cache.php under /wp-content/object-cache.php and nothing happens. There's no indication of the cache working anywhere in the WP admin, site load speed has not changed.

If I try copying the file under /wp-content/plugins/memcached/object-cache.php it shows up as a plugin on the WP Plugins section but can't turn it on as it can't redeclare wp_cache_add()

Memcached is installed and running properly, stats show some bytes written/read so maybe it's actually working? Can't know for sure without browsing through the cache...

Also I run WPMU, does that make any difference?

Cheers!

Cache clearance

Hi, we have been using your memcached plugin for what is probably years now but in the past couple of weeks we have noticed the cache clearance isn't working as usual. Usually WP Admin changes take effect immediately but in some cases (almost randomly) changes do not take effect without a delay. Is there any known issue we should be aware of?

exclude wp-admin

Hi, how to exclude wp-admin from memcached? because after did something on wp-admin (such as edit post, or upload image) the content won't change

Add support for `wp_cache_flush_group()`

Desired Behavior

WordPress 6.1 will add the new function wp_cache_flush_group(), see https://core.trac.wordpress.org/ticket/4476:

Currently, you have to specify the id of the cached item in order to delete it via wp_cache_delete, or you have to flush the entire cache via wp_cache_flush.
Instead, it would be helpful if one were able to delete an entire group without having to flush all of the cache[s].

Please consider utilizing that function in the Memcached drop-in (https://github.com/Automattic/vip-go-mu-plugins/blob/develop/drop-ins/object-cache/object-cache-next.php).

Actual Behavior

Currently, wp_cache_flush_group() is not used in the drop-in.

Additional notes

It certainly would be necessary to wrap the function call with an if ( function_exists( 'wp_cache_flush_group' ) ) check.

must not fail if MemCache class isn't available

It can occur during a lot of situation:

  • enabled in FPM but not in CLI (so wp-cli fails): I guess it's shouldn't even load if PHP_SAPI === 'cli'
  • during a PHP socket switch / version upgrade
  • during a debugging attempt that imply deactivating so PHP modules
  • ...

In all these and others cases, the extensions should definitely NOT trigger a fatal error.

Causes fatal error wil all wp-cli commands

I have tried both the "official" version of this listed on the WP Plugins "memcached", as well as just trying the version from this repo, which is slightly different.

Memcached server & PECL memcache extension are both installed and working. And both versions of the plugin work fine.

...Except that they both cause a fatal error whenever I try to use wp cli to do anything. And because they are drop ins rather than "regular" plugins, --skip-plugins does not work.

Have also tried the Use Memcached plugin, which is a "standard" WP plugin. It also breaks wp cli, but responds to --skip-plugins=use-memcached. However that plugin breaks the rest of my site (which is being used as a headless backend to JS framework frontend, so specifically seems to be breaking the REST API & WPGraphQL...but I digress).

With this particular version (of object-cache.php from this repo), the wp cli error is:
Fatal error: Uncaught Error: Class 'Memcache' not found
...on line 1073

The full message is attached as image here:
image

...since wp cli in critical to our workflow, and flushing the cache from the cli an often used function, renaming object-cache.php to object-cache.php.OFF is not a particularly good work around.

Am suspecting the bug may be with wp cli, so reporting the issue there too.

Thanks much,
Morgan
🙏

[inquiry] - is this plugin still actively being supported?

Hello,
I have 2 questions:

  1. is this plugin still actively being maintained?
  2. is wp.com using it on their stack?

Asking because in the plugin repo we see:

This plugin hasn’t been tested with the latest 3 major releases of WordPress. It may no longer be maintained or supported and may have compatibility issues when used with more recent versions of WordPress.

Explain WP_CACHE_KEY_SALT in README

When using the object-cache.php drop-in with multiple sites, users will see unexpected behaviour (such as being redirected to site A when they attempt to load site B).

To avoid this, one must define WP_CACHE_KEY_SALT in wp-config.php.

It would be very helpful to put this in the README.

$found parameter to wp_cache_get() is incorrect when object is in local cache

Due to how this drop-in caches data internally, $found will become true after the first GET, even if it doesn't exist in Memcache.

This is at best confusing, and at worst causes code to think the value in memcache is false, when it doesn't actually exist.

wp> $found = null;
wp> wp_cache_get( 'foo', null, false, $found );
bool(false)
wp> $found;
bool(false)
wp> wp_cache_get( 'foo', null, false, $found );
bool(false)
wp> $found;
bool(true)

Initialize stats array keys to prevent PHP warnings

NOTICE: wp-content/object-cache.php:348 - Undefined index: set
wp_dashboard_setup, wp_check_browser_version, set_site_transient, wp_cache_set, WP_Object_Cache->set
NOTICE: wp-content/object-cache.php:188 - Undefined index: delete
wp_dashboard, do_meta_boxes, call_user_func, wp_dashboard_quick_press, get_default_post_to_edit, wp_insert_post, wp_set_post_categories, wp_set_post_terms, wp_set_object_terms, wp_cache_delete, WP_Object_Cache->delete

$found parameter to wp_cache_get() is incorrect when object is in local cache in a non-persistent group

On the back of #40 & #43 that changed the behaviour of the $found parameter to reflect the status of the data in memcache, however, it breaks a different-but-similar case: non-persistent groups.

For example:

wp> wp_cache_add_non_persistent_groups( [ 'example' ] );
NULL

wp> wp_cache_set( 'example', 'example', 'example' );
bool(true)

wp> wp_cache_get( 'example', 'example', false, $found );
string(7) "example"

wp> $found
bool(false)

In this case, the value was never going to exist within memcache and it was found in the cache, so I would argue that $found should be true in this case.

I personally ran into this with Cavalcade, where it relies upon the $found parameter working with non-persistent groups: https://github.com/humanmade/Cavalcade/blob/master/inc/class-job.php#L366-L368

Key rotation does not work properly on 32-bit php

A bit of an edge case now, but intval( microtime( true ) * 1e6 ) in rotate_site_keys() and rotate_global_keys() can overflow in 32-bit integers and the memcached daemon throws errors if the Memcache::increment method is called on a negative value.

Checking for PHP_INT_SIZE == 4 and just using time() instead of microtime() is a quick fix.

Automatically Disable object-cache.php on Core Update

We found with the latest WordPress v6.5 update that when updating core, it is not just necessary to rename or delete object-cache.php but also to then flush the cache before re-enabling object-cache.php.

If this doesn't happen, when you try to access the dashboard, the site tries to update the WordPress database but displays a notice to say it's already been updated and directs the user to the home page rather than the dashboard preventing access to the dashboard until object-cache.php has been disabled or the cache has been flushed.

Is there a way to automatically disable object-cache.php when a core update is in progress then flush the cache and re-enable object-cache.php when the update is successful?

I feel like this may also be required when performing plugin updates or even theme updates?

This issue probably presented on previous core updates but we're new to Memcached.

Oliver

Is this compatible with WP Super Cache ?

Hello,
Our company currently use page caching with WP Super Cache which is really great :)

Since WordPress 6.1 there is a "object cache" health warning in WordPress.

Besides, some of our customers use heavy (bought) themes/templates with N+1 queries, many loops, etc. making some pages load slowly when not cached (sometimes more than 2 seconds with repeated SQL queries).

Could we just install wp-memcached to improve this ? Will it work with WP Super Cache ? Or is it better to use a single plugin (maybe BatCache or W3 Total Cache) ?

Moreover, we use nginx_mod_pagespeed to optimize JS/CSS/HTML, but this module has been abandoned by the Apache foundation so we will soon have to remove it. Maybe W3 Total Cache would cover it all ? Or is there a better solution ?

Thank you for your great plugins and for your help :)
Mathieu.

[Feature request/question] How to disable for a single website in wpmu ?

Hello,
Thank you for this module, it rocks :)

Is it possible to disable the cache object on a specific website in a wordpress network ? Is there any constant and/or filter we could use ?

As I could not find it I added a filter in the object-cache.php but I'm not sure if it's required and/or in the right place :

function wp_cache_set( $key, $data, $group = '', $expire = 0 ) {
        global $wp_object_cache;

        if ( defined( 'WP_INSTALLING' ) == false && apply_filters( 'ircf_wp_cache_disabled', false ) == false) {
                return $wp_object_cache->set( $key, $data, $group, $expire );
        } else {
                return $wp_object_cache->delete( $key, $group );
        }
}

Thank you very much :)
Mathieu.

Prevent fatals upon plugin activation

This object cache is distributed on https://wordpress.org/plugins/memcached/ as a plugin, but can't actually be used as one. The installation instructions do suggest it requires extra configutaration, but since most plugins only have junk there, no-one looks at it.

Due to the number of end-users who attempt to install it (See the support threads), only to be met with a fatal error, we should disable the plugin activation aspect of the plugin and present a useful error message to the end-user, rather than simply showing a fatal error.

I'm not sure of the best method to achieve this, but if it's going to be on WordPress.org/plugins it would be great to remove that "limitation".

New release

Hi,

Just wondering, would it be possible to get a new release out, there's a lot of servers out there writing deprecation notes to the error logs.

The plugin is awesome, thanks for maintaining it!

Best regards,
Ed

Limit cache key length

Memcache has a key length limit of 250 characters. Problems can arise if a cache key greater than this is used. It seems memcache truncates the key so it is very possible to have collisions and unexpected behavior. Other object caches can handle very large keys so this object cache should check if a key is too long and hash it with md5 or similar to prevent problems.

Cron events cause PHP timeout

Hi,

We have a cron event that when run can occasionally take some time to complete, especially if previous instances have failed as there is more to do.

The site in question runs perfectly in all other aspects with object-cache.php installed however, we have since discovered that we see the following errors in debug.log ...

[19-Mar-2024 16:49:06 UTC] PHP Fatal error:  Maximum execution time of 30 seconds exceeded in /wp-content/object-cache.php on line 790
[19-Mar-2024 16:49:06 UTC] E_ERROR: Maximum execution time of 30 seconds exceeded in /wp-content/object-cache.php on line 790
[19-Mar-2024 16:52:56 UTC] PHP Fatal error:  Maximum execution time of 30 seconds exceeded in /wp-content/object-cache.php on line 790
[19-Mar-2024 16:52:56 UTC] E_ERROR: Maximum execution time of 30 seconds exceeded in /wp-content/object-cache.php on line 790
[19-Mar-2024 16:53:29 UTC] PHP Fatal error:  Maximum execution time of 30 seconds exceeded in /wp-content/object-cache.php on line 790
[19-Mar-2024 16:53:29 UTC] E_ERROR: Maximum execution time of 30 seconds exceeded in /wp-content/object-cache.php on line 790

When object-cache.php is deleted the issue no longer presents itself.

Why would having the object-cache.php installed introduce a PHP execution time limit?

Please advise.

Many thanks,

Oliver

Missing $found param for wp_cache_get

The correct implementation has a $found reference param, because your cache should allow any possible return value. Otherwise you'll never be able to cache false values.

function wp_cache_get( $key, $group = '', $force = false, &$found = null )

Why not Memcached Class?

Hi everyone,

maybe a silly question here: but why don't use Memcached (with the d) in this implementation? It seems that in php7.0 memcached is preferred (or am I wrong?)

Add to local cache even if memcache add fails

I recently encountered pathological behaviour when Memcache writes succeed but reads fail.

As a summary of what the conditions/behaviour of wp-memcached v4.0.0 and a single key:

  • on request 1, memcache add succeeds and the key is written to both the local cache and memcache.
  • consider request 2 get: initially the local cache lookup fails, the memcache lookup fails†, but memcache add also fails down the ([mc already]) path because the existing cache value is detected. This path does not write to the local cache:
    if ( false !== $result ) {
    $this->cache[ $key ] = [
    'value' => $data,
    'found' => true,
    ];
  • all subsequent lookups in request 2 also fail in an expensive way (there's nothing in the local cache, they go away and do some SQL queries, then they call add again). For keys like alloptions, this means hundreds of SQL queries.

† why does the memcache lookup fail after a successful add? Well, in my case it was because wp-memcached and Google's Memcache API had different assumptions about memcache flag support (I've raised a bug with Google). But there are other realistic scenarios, such as memcache being unavailable (e.g. failing all get operations) or memcache servers that only provide eventual consistency.

I understand that the existing behaviour is intentional: by not setting the local cache when the write fails, we would normally expect the next call to get to succeed in a memcache lookup and then populate the local cache. But admins add the Memcached Object Cache in order to improve performance and reliability, so if the memcached starts failing reads, the performance degradation and SQL server load will actually be much worse than the default WordPress behaviour with a local object cache (which limits key lookups to once per request). The downside seems to be that the add is only going to get retried once per request (rather than once per lookup), which seems like an acceptable trade-off to me.

If the maintainers agree, I can send a PR. Also open to some class option similar to default_expiration that could be set in one place to opt in to my proposed local caching behaviour.

Implement `wp_cache_flush_runtime()`

WP 6.0 introduced wp_cache_flush_runtime(). As of WordPress/wordpress-develop@c204a6a, the method is called in WP's unit test framework, triggering this error:

Unexpected incorrect usage notice for wp_cache_flush_runtime.
Your object cache implementation does not support flushing the in-memory runtime cache. (This message was added in version 6.1.0.)

Multiple default groups shown in Stats

Screenshot 2020-10-16 at 10 53 24

There are two default groups in this list - in the 2nd and 6th positions.

When clicking the one in the 6th position, then the list for the one in the 2nd position appear in the panel below this list i.e. I can't access details of the requests that had 163 bytes.

There appears to be a couple of instances (1, 2) where a missing group name gets set as default, and it's the group name that is used for the toggle.

Stats: Revert back to limiting ops?

Prior to 3.2.0 we limited the number of ops shown to 500. I believe it would still be good to have a soft limit like this. When debugging sites with caching issues, that are doing tens or hundreds of thousands of ops per transaction, this can cause the browser to lock up trying to load and parse all of the data.

Now, it's obvious that the site is _doing_it_wrong() but having the ability to use Debug Bar to help debug the issue and related issues would be really helpful.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.