Caching on highload Drupal site - Alexander Shumenko

1,860 views

Published on

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

Published in: Internet
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,860
On SlideShare
0
From Embeds
0
Number of Embeds
155
Actions
Shares
0
Downloads
5
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Caching on highload Drupal site - Alexander Shumenko

  1. 1. 25 -27 April, 2014 http://camp2014.drupal.dn.ua Caching on highload Drupal site.
  2. 2. ❏Как мы работаем с кешем в Drupal ❏Зачем нам нужны цепочки тегов ❏Принцип построения цепочки тегов ❏Где можно использовать цепочки тегов ❏Частный пример использования О чем мы сегодня будем говорить
  3. 3. 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; } Проверка доступности кешированных данных. Операции с какими либо данными. Сохранение данных в кеш Обычная работа с кешем
  4. 4. ❏Всегда знаем в каком кеше участвуют данные ❏Возможность получить управляемый кеш ❏Высокая релевантность данных хранимых в кеше ❏Снижение нагрузки на сайт при очистке кеша Зачем нам нужны цепочки тегов
  5. 5. Время потраченное на генерацию страницы Для примера возьмем ноду, при выводе которой используется еще 10 референс нод Без кеширования Контент из кеша 700 мс 1 мс
  6. 6. Схема построения цепочки Drupal callback Browser Request Response Cache get Cache start Cache tag Cache tag applyCache set Using generated tags
  7. 7. Принцип построения цепочки тегов Знаем момент начала и конца работы с кешируемыми данными Можем сопроводить наши данные и составить цепочку тегов 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; }
  8. 8. Необходимо сделать механизм гибкого кеширования данных, с учетом отображения специфической информации в зависимости от контекста кешируемых данных. Разделение кеша
  9. 9. Разделение кеша ❏ Разделить кеш нам поможет уникальный 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, ));
  10. 10. 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
  11. 11. /** * 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. Открытие цепочки тегов Cache start
  12. 12. /** * 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” Создание тега Cache tag
  13. 13. /** * 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” Добавление тега в цепочку Cache tag apply
  14. 14. /** * 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
  15. 15. Связь с Drupal кешем Чтоже делать с полученной цепочкой тегов? Например мы можем ее использовать для очищения только нужного кеша в Drupal. Для этого нам понадобится таблица для связи cache id и тегов которые участвовали в создании этого кеша. Эта таблица может быть такого вида: Поле cid bin expire tags Тип поля varchar varchar int text Описание Хранит кеш ID для связи с кешем Храним имя корзины чтобы в последующем найти кеш Срок жизни кеша Теги примененные к кешу В эту таблицу мы будем производить запись сразу после того как закрываем цепочку тегов. Таким образом мы получаем связь между таблицей кеша и полученными тегами и можем найти и очистить кеш в который маркирован этими тегами.
  16. 16. Где можно использовать цепочки тегов 1. При стандартном кешировании в Drupal. 2. Теги можно проставлять в загловок страницы и использовать как cache id для кеширования данных реверс прокси сервером, к примеру Varnish. 3. В целом полученные теги Вы можете адаптировать к любой системе кеширования.
  17. 17. THANK YOU! Шуменко Александр Adyax Company Email: alexander.shumenko@gmail.com Skype: alexander.shumenko

×