Skip to content

Commit

Permalink
Merge pull request #2047 from Automattic/update/alloptions-limit
Browse files Browse the repository at this point in the history
ALLOPTIONS limit alert/block - account for the fact that pecl-memcache client automagically compresses the values before sending it to the server
  • Loading branch information
rinatkhaziev authored Mar 29, 2021
2 parents 60a80a8 + 563ce16 commit 414e8a7
Showing 1 changed file with 23 additions and 5 deletions.
28 changes: 23 additions & 5 deletions alloptions-limit.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,34 @@ function wpcom_vip_sanity_check_alloptions() {
}

// Warn should *always* be =< die
$alloptions_size_warn = 800000;
$alloptions_size_die = 1000000; // 1000000 ~ 1MB, too big for memcache
$alloptions_size_warn = 800000;
// 950000 is slightly less than ~ 1MB, which is the Memcached entry limit.
// The purpose of this limit is to safe-guard against a barrage of requests with cache sets for values that are too large
// Because WP would keep trying to set the data to Memcached, potentially resulting in Memcached (and site's) performance degradation.
$alloptions_size_die = 950000;

$alloptions_size = wp_cache_get( 'alloptions_size' );

// Cache miss
if ( false === $alloptions_size ) {
$alloptions = wp_load_alloptions();

$alloptions_size = strlen( serialize( $alloptions ) );
$alloptions = serialize( wp_load_alloptions() );
$alloptions_size_uncompressed = strlen( $alloptions );
// We're using gzdeflate here because pecl-memcache uses Zlib compression for large values.
// See https://github.com/websupport-sk/pecl-memcache/blob/e014963c1360d764e3678e91fb73d03fc64458f7/src/memcache_pool.c#L303-L354
$alloptions_size_compressed = strlen( gzdeflate( $alloptions ) );

// We only compress the value if it's bigger than 20kb and the savings for the compressed value are more than 20%;
// See https://github.com/Automattic/wp-memcached/blob/811243804a892a4609a4581d9479fa80c4e4ac8d/object-cache.php#L782
// Make sure to use the correct size.
// This is an additional safe-guard, in reality the bigger the value the better the compression,
// So it's hard to get into a situation where you have a large value that not going to have at least 20% savings.
$diff = $alloptions_size_uncompressed - $alloptions_size_compressed;

if ( $alloptions_size_uncompressed > 20000 && $diff > $alloptions_size_uncompressed * 0.2 ) {
$alloptions_size = $alloptions_size_compressed;
} else {
$alloptions_size = $alloptions_size_uncompressed;
}

wp_cache_add( 'alloptions_size', $alloptions_size, '', 60 );
}
Expand Down

0 comments on commit 414e8a7

Please sign in to comment.