Cache bin is not part of cache ID prefix, could cause collisions

Created on 24 February 2023, about 2 years ago

Problem/Motivation

While reviewing the code, I noticed that MemcacheBackend::set does not use the cache bin ID as a prefix for the cache ID. This is done with APCu and Redis stores to prevent collisions.

https://git.drupalcode.org/project/memcache/-/blob/8.x-2.x/src/MemcacheB...

APCu sites a prefix based on the %site.path% and bin ID to prevent collisions:

$this->binPrefix = $this->sitePrefix . '::' . $this->bin . '::';
...
$this->binPrefix . $cid;

Redis does something similar, where the prefix piggybacks on the APCu one (https://git.drupalcode.org/project/redis/-/blob/8.x-1.x/src/RedisPrefixT...):

$this->getPrefix() . ':' . $this->bin . ':' . $cid;

Steps to reproduce

I haven't, but I'd assume use two different cache bins and create two cache items of the same ID.

Proposed resolution

Add a prefix to cache IDs.

Remaining tasks

User interface changes

API changes

Data model changes

πŸ› Bug report
Status

Closed: cannot reproduce

Version

2.0

Component

Code

Created by

πŸ‡ΊπŸ‡ΈUnited States mglaman WI, USA

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

  • Issue created by @mglaman
  • πŸ‡ΊπŸ‡ΈUnited States mglaman WI, USA

    This existed in D7 https://git.drupalcode.org/project/memcache/-/blob/7.x-1.x/dmemcache.inc... and did work to handle the max length of key names

      // Memcache truncates keys longer than 250 characters[*]. This could lead to
      // cache collisions, so we hash keys that are longer than this while still
      // retaining as much of the key bin and name as possible to aid in debugging.
      // The hashing algorithm used is configurable, with sha1 selected by default
      // as it performs quickly with minimal collisions. You can enforce shorter
      // keys by setting memcache_key_max_length in settings.php.
      // [*]https://github.com/memcached/memcached/blob/master/doc/protocol.txt#L47
      $maxlen = variable_get('memcache_key_max_length', 250);
    
      foreach ($full_keys as $k => $full_key) {
        if (strlen($full_key) > $maxlen) {
          $full_keys[$k] = urlencode($prefix[$k] . $bin) . '-' . hash(variable_get('memcache_key_hash_algorithm', 'sha1'), $key);
          $full_keys[$k] .= '-' . substr(urlencode($key), 0, ($maxlen - 1) - strlen($full_keys[$k]) - 1);
        }
      }
    
    
  • Status changed to Closed: cannot reproduce about 2 years ago
  • πŸ‡ΊπŸ‡ΈUnited States mglaman WI, USA

    Whoops! It was in the driver class: \Drupal\memcache\Driver\DriverBase::key

Production build 0.71.5 2024