17
25 -27 April, 2014 http:// camp2014.drupal.dn.ua Caching on highload Drupal site.

Caching on highload Drupal site - Alexander Shumenko

Embed Size (px)

DESCRIPTION

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

Citation preview

Page 1: Caching on highload Drupal site - Alexander Shumenko

25 -27 April, 2014

http://camp2014.drupal.dn.ua

Caching on highload Drupal site.

Page 2: Caching on highload Drupal site - Alexander Shumenko

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

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

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

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

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

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

Page 3: Caching on highload Drupal site - Alexander Shumenko

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;

}

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

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

Page 4: Caching on highload Drupal site - Alexander Shumenko

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

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

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

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

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

Page 5: Caching on highload Drupal site - Alexander Shumenko

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

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

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

700 мс

1 мс

Page 6: Caching on highload Drupal site - Alexander Shumenko

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

Drupal callback

Browser

Request

Response

Cache get

Cache start

Cache tag

Cache tag applyCache set

Using generatedtags

Page 7: Caching on highload Drupal site - Alexander Shumenko

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

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

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

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;}

Page 8: Caching on highload Drupal site - Alexander Shumenko

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

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

Page 9: Caching on highload Drupal site - Alexander Shumenko

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

❏ Разделить кеш нам поможет уникальный 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, ));

Page 10: Caching on highload Drupal site - Alexander Shumenko

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

Page 11: Caching on highload Drupal site - Alexander Shumenko

/** * 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

Page 12: Caching on highload Drupal site - Alexander Shumenko

/** * 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

Page 13: Caching on highload Drupal site - Alexander Shumenko

/** * 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

Page 14: Caching on highload Drupal site - Alexander Shumenko

/** * 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

Page 15: Caching on highload Drupal site - Alexander Shumenko

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

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

Поле cid bin expire tags

Тип поля varchar varchar int text

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

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

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

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

Page 16: Caching on highload Drupal site - Alexander Shumenko

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

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

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

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

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

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

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

Page 17: Caching on highload Drupal site - Alexander Shumenko

THANK YOU!

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

Adyax Company

Email: [email protected]: alexander.shumenko