📜 ⬆️ ⬇️

Namespaces in memcahced

I am sure that many here have already encountered the problem of data caching in their projects. I am also sure that many have already used memcached for this. Recently, this all had to face me =). But I also had the opportunity to work with the namespaces in memcached.
Unfortunately, memcahced has no support for this convenient opportunity, but this is not a reason to despair and get depressed =)


I needed namespaces in order to mark portions of the data in the cache as not valid if some of this data was already marked as invalid. Here is a simple example:
I have an object that can be selected from the database both by itself and among other objects with the help of a mass SELECT; Thus, if you cache a single object and a massive sample from the database, then when updating a single object and invalidating its cache, the problem of invalidation of the sample cache arises. And such samples saved in the cache can be much more than one.

Having broken his head for a long time, inventing various key combinations, I decided to return to the documentation for memcached ... And about a miracle (I had to read more carefully for the first time =)) - in the FAQ I found the lines that solved my problem:
')
$ns_key = $memcache->get("foo_namespace_key");

// if not set, initialize it
if($ns_key===false) $memcache->set("foo_namespace_key", rand(1, 10000));

// cleverly use the ns_key
$my_key = "foo_".$ns_key."_12345";
$my_val = $memcache->get($my_key);

//To clear the namespace do:
$memcache->increment("foo_namespace_key");

Maybe someone did not immediately understand everything after reading this piece of code, so I will explain what is “happening” here:

$ns_key = $memcache->get("foo_namespace_key");

Everything is simple, we get the namespace key from the cache using the key " foo_namespace_key " (this can be called the namespace name).

if($ns_key===false) $memcache->set("foo_namespace_key", rand(1, 10000));

This is the initialization of the namespace (in my case, I used as the initial value 0). The namespace needs to be initialized with an integer value. What for? Find out a little later.

$my_key = "foo_".$ns_key."_12345";
$my_val = $memcache->get($my_key);


This is an example of using the namespace. Those. we combine the value we received from the cache with the key " foo_namespace_key " (“inline”) with the key for data storage and then save the necessary data using this key. Example:
  1. At first, our list is not initialized.
  2. Write the value 0 to the namespace cache.
  3. As a result, $ my_key will have the value " foo_0_12345 "
  4. We save data on this key

$memcache->increment("foo_namespace_key");

Well, this is a namespace invalidation (the increment function increases the value stored by a given key by 1 or the value specified as the second parameter). Thus, in my example, the value stored in the cache by the key " foo_namespace_key " will increase and will equal 1. Therefore, the cache cell with the key $ my_key = "foo _". $ Ns_key. "_ 12345" will be empty, because $ my_key will be " foo_1_12345 ", and the old data will be stored by the key " foo_0_12345 " and will not be available through the call through the namespace, they will no longer be accessed and over time they will be forced out of the cache.

In the case of my objects and mass sampling, this method finds its place in the following case: All mass selections are stored in the Objects namespace, and the single objects in Object . Thus, when changing or deleting a single object, I invalidate the Objects namespace, and when I update or delete it on a massive scale, I also invalidate Objects and Object, which allows us to keep the data in the cache current.

Source: https://habr.com/ru/post/55265/


All Articles