Caching on highload Drupal site - Alexander Shumenko

  • View
    1.618

  • Download
    5

  • Category

    Internet

Preview:

DESCRIPTION

Рассмотрим создание тегированной системы кеширования сущностей для high load сайта на Drupal. В ходе доклада будут рассмотрены наиболее интересные моменты реализации (построение цепочки тегов) так же рассмотрены проблемы и способы их решения.

Citation preview

25 -27 April, 2014

http://camp2014.drupal.dn.ua

Caching on highload Drupal site.

❏Как мы работаем с кешем в Drupal

❏Зачем нам нужны цепочки тегов

❏Принцип построения цепочки тегов

❏Где можно использовать цепочки тегов

❏Частный пример использования

О чем мы сегодня будем говорить

function my_module_function() { // Проверяем доступен ли кеш if ($cache = cache_get('my_module_data')) { // Если да то возвращаем данные. $my_data = $cache->data; } else { // Если кеш недоступен то выполняем нужные операции. $my_data = my_module_get_some_data(); // Сохраянем кеш. cache_set('my_module_data', $my_data, 'cache'); } return $my_data;

}

Проверка доступности кешированных данных.Операции с какими либо данными. Сохранение данных в кеш

Обычная работа с кешем

❏Всегда знаем в каком кеше участвуют данные

❏Возможность получить управляемый кеш

❏Высокая релевантность данных хранимых в кеше

❏Снижение нагрузки на сайт при очистке кеша

Зачем нам нужны цепочки тегов

Время потраченное на генерацию страницы

Для примера возьмем ноду, при выводе которой используется еще 10 референс нод

Без кеширования Контент из кеша

700 мс

1 мс

Схема построения цепочки

Drupal callback

Browser

Request

Response

Cache get

Cache start

Cache tag

Cache tag applyCache set

Using generatedtags

Принцип построения цепочки тегов

Знаем момент начала и конца работы с кешируемыми данными

Можем сопроводить наши данные и составить цепочку тегов

function my_module_function() { $cache_id = ‘some_id’; if ($cache = qtools_api__cache_get($cache_id, 'cache')) { $mydata = $cache->data; } else { // Момент начала работы с кешем. $locked = qtools_api__cache_start($cache_id); $mydata = my_module_get_some_data();

if ($locked) { // Создаем и применяем тег. $tag = qtools_api__cache_tag(‘node’, ‘1’); qtools_api__cache_tag_apply($tag); // Момент когда работа с кешем закончена. $tags = qtools_api__cache_set($cache_id, $mydata, 'cache', ‘600’); } } return $mydata;}

Необходимо сделать механизм гибкого кеширования данных, с учетом отображения специфической информации в зависимости от контекста кешируемых данных.

Разделение кеша

Разделение кеша

❏ Разделить кеш нам поможет уникальный cache_id.❏ Для данных хорошим вариантом при генерации cache_id будет использование

глобальных данных относящихся к этому кешу, например язык на котором он доступен, id домена, роли пользователя.

Пример генерации cache_id используемый при рендере сущности:

$cache_id = implode(':', array( $entity_type, $entity_id, $view_mode, implode('_', array_keys($user->roles)), $domain['domain_id'], $language->language, ));

function qtools_api__cache_get($cid, $bin = 'cache', $wait = 3, $stale = 60) { $lid = 'qtools_api__cache_lock:' . $cid; // Check if we not rebuilding this $cid. if ($wait > 0 && !lock_may_be_available($lid)) { if (lock_wait($lid, $wait) == FALSE) { // If not we only interested in cache that does not expire. $stale = 0; } } else { // Rely only on expire if wait = 0. $stale = 0; } // Load cache from a bin. $cache = cache_get($cid, $bin); // Reset cache if it is expire, or temporary. if (!empty($cache) && !empty($cache->expire) && ($cache->expire < (time() - $stale))) { $cache = NULL; } // Return cache if exists. return $cache;}

Функция получения кеша, использует стандартный cache_get Drupal.

Также добавлена проверка на время жизни кеша.

Cache get

/** * Cache start. */function qtools_api__cache_start($cid, $lock = 30) { // Prepare fresh tags array. $tags = &drupal_static('qtools_api__cache_tag', array()); $tags[$cid] = array(); // Attempt to aquire lock. $lid = 'qtools_api__cache_lock:' . $cid; return lock_acquire($lid, $lock);}

Работу с цепочкой начинаем функцией ее открытия, объявляем статик переменную где будем хранить цепочку, и ставим lock.

Открытие цепочки тегов

Cachestart

/** * Make simple tag. */function qtools_api__cache_tag($type, $value) { $short = qtools_api__cache_tag_short(); if (!empty($short[$type])) { $type = $short[$type]; } // Normalize tag. $tag = current(qtools_api__cache_tags_prepare($type . '|' . $value)); return $tag;}

Эта функция создает тег, также тут мы пытаемся получить шорт имя для тега.В результате выполнения для ноды с nid=1 получим тег вида “n|1”

Создание тега

Cachetag

/** * Cache tag. * If seed are not specified mark all opened cache pipes. * Note that any ';' will be replaced with dash. */function qtools_api__cache_tag_apply($tag, $cids = array()) { $tags = &drupal_static('qtools_api__cache_tag', array()); $keys = !empty($cids) ? $cids : array_keys($tags); // Normalize tag. $tag = qtools_api__cache_tags_prepare($tag); $return = array(); foreach ($keys as $key) { if (isset($tags[$key])) { $tags[$key] = array_unique(array_merge($tags[$key], array_values($tag))); $return[$key] = $tags[$key]; } } return $return;}

Собираем цепочку из тегов. На выходе будем иметь теги всех данных участвовавших в генерации контента. Пример цепочки “n|5376;n|1285;t|165;n|530;n|

169;n|214”

Добавление тега в цепочку

Cachetag

apply

/** * Cache set. */function qtools_api__cache_set($cid, $data, $bin = 'cache', $expire = CACHE_PERMANENT) { $track_tags = qtools_api__cache_tags_for($cid, TRUE); // Add tags to cache object if required. if (is_array($data) && isset($data['tags']) && is_array($data['tags'])) { $data['tags'] = array_unique(array_merge($data['tags'], $track_tags)); } // Set cache. cache_set($cid, $data, $bin, $expire); // Release lock. $lid = 'qtools_api__cache_lock:' . $cid; lock_release($lid); return $track_tags;}

Сохраняем кеш и снимаем lock

Возвращаем полученную цепочку тегов

Cache set

Сохраняем кеш

Cache set

Связь с Drupal кешем

Чтоже делать с полученной цепочкой тегов? Например мы можем ее использовать для очищения только нужного кеша в Drupal. Для этого нам понадобится таблица для связи cache id и тегов которые участвовали в создании этого кеша. Эта таблица может быть такого вида:

Поле cid bin expire tags

Тип поля varchar varchar int text

Описание Хранит кеш ID для связи с кешем

Храним имя корзины чтобы в последующем найти кеш

Срок жизни кеша Теги примененные к кешу

В эту таблицу мы будем производить запись сразу после того как закрываем цепочку тегов.Таким образом мы получаем связь между таблицей кеша и полученными тегами и можем найти и очистить кеш в который маркирован этими тегами.

Где можно использовать цепочки тегов

1. При стандартном кешировании в Drupal.

2. Теги можно проставлять в загловок страницы и

использовать как cache id для кеширования данных

реверс прокси сервером, к примеру Varnish.

3. В целом полученные теги Вы можете адаптировать к

любой системе кеширования.

THANK YOU!

Шуменко Александр

Adyax Company

Email: alexander.shumenko@gmail.comSkype: alexander.shumenko

   

Recommended