Как стать автором
Обновить

Пространства имен в memcahced

Время на прочтение 3 мин
Количество просмотров 1K
Уверен, что многие здесь уже сталкивались с проблемой кеширования данных в своих проектах. Также я уверен, что многие уже использовали для этого memcached. Недавно с этим всем пришлось столкнуться и мне =). Но также мне была инетресна возможность работать с пространствами имен в memcached.
К сожалению у memcahced нет поддержки этой удобной возможности, но это не повод, чтобы отчаяться и впасть в депрессию =)


Пространства имен мне понадобились для того, чтобы отмечать порции данных в кеше как не действительные, если часть этих данных уже была отмечена как недействительная. Вот простой пример:
у меня есть объект, который может выбираться из БД как сам по себе, так и среди других объектов с помощью массового SELECT'а; таким образом, если кешировать одиночный объект и массовую выборку из БД, то при обновлении одиночного объекта и инвалидации его кеша, возникает проблема инвалидации кеша выборки. А таких выборок, сохраненнных в кеш, может быть гораздо бльше чем одна.

Долго поломав себе голову, придумывая всевозможные комбинации ключей, решил вернуться к документации к memcached… И о чудо (надо было внимательнее читать в первый раз =)) — в FAQ'e я нашел строчки, решившие мою проблему:

$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");

Может кому-то сразу не все стало понятно после прочтения этого куска кода, поэтому я поясню, что здесь «происходит»:

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

Тут все просто, получаем ключ пространства имен из кеша по ключу "foo_namespace_key" (это можно назвать именем пространства имен).

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

Это инициализация пространства имен (в моем случае я использовал в качетсве начального значения 0). Пространсвто имен нужно инициализировать целочисленным значением. Зачем? Узнаете чуть позже.

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


Это пример использование пространства имен. Т.е. то значение, которое мы получили из кеша по ключу "foo_namespace_key", мы совмещаем («встраиваем») с ключем для хранения данных и потом по этому ключу сохраняем необходимые данные. Пример:
  1. Снача у нас список не инициализирован
  2. Записываем в кеш пространства имен значение 0
  3. В результате $my_key будет иметь значение "foo_0_12345"
  4. Сохраняем данные по этому ключу

$memcache->increment("foo_namespace_key");

Ну а это инвалидация пространства имен (функция increment увеличивает хранимое по заданному ключу значение на 1 или же на величину указанную в качестве второго параметра). Таким образом, в моем примере значение, хранящее в кеше по ключу "foo_namespace_key" увеличится и будет равняться 1. Следовательно, ячейка кеша с ключему $my_key = «foo_».$ns_key."_12345" будет пуста, потому что $my_key будет равен "foo_1_12345", а старые данные будут храниться по ключу "foo_0_12345" и будут не доступны через обращение через пространство имен, обращения к ним больше не будет и со временем они будут вытеснены из кеша.

В случае с моими объектами и массовой выборкой этот метод находит свое место в следующем случае: Все массовые выборки храняться в пространстве имен Objects, а единичные объекты — в Object. Таким образом при изменении или удалении одиночного объекта, я инвалидирую пространство имен Objects, а при массовом обновлении или удалении я инвалидирую и Objects, и Object, что позволяет сохранить актуальность данных в кеше.
Теги:
Хабы:
+2
Комментарии 10
Комментарии Комментарии 10

Публикации

Истории

Ближайшие события

PG Bootcamp 2024
Дата 16 апреля
Время 09:30 – 21:00
Место
Минск Онлайн
EvaConf 2024
Дата 16 апреля
Время 11:00 – 16:00
Место
Москва Онлайн
Weekend Offer в AliExpress
Дата 20 – 21 апреля
Время 10:00 – 20:00
Место
Онлайн