Last active
April 7, 2022 17:35
-
-
Save phizev/618ae544dca73abae492cbade8eae13b to your computer and use it in GitHub Desktop.
In short: Performance improvement, and a 50% reduction in cache_form, no negatives. Drupal database cache implementation using igbinary_(un)serialize().
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Rationale: | |
igbinary does an excellent job at creating compact serialized data as opposed to | |
PHP's serializer. It's already used for serializing data stored in memcached, | |
Drupal's form cache can get notoriously large, can igbinary help? | |
https://github.com/igbinary/igbinary | |
Experimentation: | |
Drupal database cache implementation using igbinary_(un)serialize(). In my initial | |
experimentation, this reduced the size of cache_form by a factor of ~2.6. In one | |
to one comparisons of the results of serializing an extremely large form, this | |
difference began to top out at ~3.2. For very small forms, such as the login form, | |
I was seeing a factor of about 2:1. While igbinary can be slower than PHP's serialise, | |
I found the difference was far outstripped by the time saved in database queries, | |
especially over a network. Note: I had compact_strings enabled. | |
I have run some sites where this cache implementation is the only one in use. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @file | |
* Functions and interfaces for cache handling. | |
*/ | |
/** | |
* Defines an igbinary databased backed cache implementation. | |
* | |
* This simply extends Drupal's default cache implementation, switching | |
* PHP's (un)serialize for igbinary_(un)serialize. It remains true to core | |
* in other manners. | |
*/ | |
class IgbinaryDatabaseCache extends DrupalDatabaseCache { | |
/** | |
* Prepares a cached item. | |
* | |
* Checks that items are either permanent or did not expire, and unserializes | |
* data as appropriate. | |
* | |
* @param $cache | |
* An item loaded from cache_get() or cache_get_multiple(). | |
* | |
* @return | |
* The item with data unserialized as appropriate or FALSE if there is no | |
* valid item to load. | |
*/ | |
protected function prepareItem($cache) { | |
global $user; | |
if (!isset($cache->data)) { | |
return FALSE; | |
} | |
// If the cached data is temporary and subject to a per-user minimum | |
// lifetime, compare the cache entry timestamp with the user session | |
// cache_expiration timestamp. If the cache entry is too old, ignore it. | |
if ($cache->expire != CACHE_PERMANENT && variable_get('cache_lifetime', 0) && isset($_SESSION['cache_expiration'][$this->bin]) && $_SESSION['cache_expiration'][$this->bin] > $cache->created) { | |
// Ignore cache data that is too old and thus not valid for this user. | |
return FALSE; | |
} | |
// If the data is permanent or not subject to a minimum cache lifetime, | |
// unserialize and return the cached data. | |
if ($cache->serialized) { | |
$cache->data = igbinary_unserialize($cache->data); | |
} | |
return $cache; | |
} | |
/** | |
* Implements DrupalCacheInterface::set(). | |
*/ | |
function set($cid, $data, $expire = CACHE_PERMANENT) { | |
$fields = array( | |
'serialized' => 0, | |
'created' => REQUEST_TIME, | |
'expire' => $expire, | |
); | |
if (!is_string($data)) { | |
$fields['data'] = igbinary_serialize($data); | |
$fields['serialized'] = 1; | |
} | |
else { | |
$fields['data'] = $data; | |
$fields['serialized'] = 0; | |
} | |
try { | |
db_merge($this->bin) | |
->key(array('cid' => $cid)) | |
->fields($fields) | |
->execute(); | |
} | |
catch (Exception $e) { | |
// The database may not be available, so we'll ignore cache_set requests. | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name = Igbinary DBcache | |
description = A copy of the Drupal core cache.inc, replacing (un)serialize() with the igbinary counterparts. | |
package = Performance and scalability | |
core = 7.x |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Implements hook_requirements(). | |
*/ | |
function igbinary_dbcache_requirements($phase) { | |
$requirements = array(); | |
$t = get_t(); | |
if ($phase == 'install' || $phase == 'runtime') { | |
$requirements['igbinary_extension']['title'] = $t('Igbinary serializer'); | |
if (extension_loaded('igbinary')) { | |
$requirements['igbinary_extension']['severity'] = REQUIREMENT_OK; | |
$requirements['igbinary_extension']['value'] = $t('Enabled'); | |
} | |
else { | |
$requirements['igbinary_extension']['severity'] = REQUIREMENT_ERROR; | |
$requirements['igbinary_extension']['value'] = $t('The PHP igbinary extension is required to use the igbinary_dbcache backend.'); | |
} | |
} | |
return $requirements; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* @file | |
* Empty .module file so that the module can be enabled to check for igbinary. | |
*/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment