Чи є спосіб підключити очищення кешу?


16

На великому веб-сайті установи, у якому є великі кеші, я хотів би створити кеші якнайшвидше, щоб жоден користувач не міг приїхати на створення кешу ...

У мене є набір хронів усі хвилини, які це роблять, виконуючи кілька функцій і запитуючи критичні сторінки, але те, що я шукаю, це спосіб дізнатися, коли кеш тільки що очищено , бажано гак, тому я можу запустити це генеруючі-функції.

Будь-яка ідея?


Залежно від того, що ви намагаєтеся зробити, відповідь Phayes вниз на сторінці - це приємне рішення для зняття коду після очищення кеш-пам'яті.
Лестер Пібоді

Відповіді:


7

Немає в Drupal 7.x, але це було додано як основний гак, кука_побудова в Drupal 8.x після того, як достатньо людей просили його. Можливо, є кращий спосіб вирішити свою проблему в 7.x, хоча - ви намагаєтеся запустити якусь функцію зігрівання кешу відразу після того, як cron очистить кеш, правильно? Іншим способом наблизитись до цього було б використання крона Elysia, який має низку суттєвих покращень у функціонуванні cron, але два, які можуть бути відповідні вашому випадку використання:

Elysia Cron розширює стандартний крон Drupal, що дозволяє чітко контролювати зерно над кожною задачею та декількома способами додати спеціальні завдання з крон на ваш сайт.

  • Встановіть терміни та частоту кожного завдання на Cron (ви можете виконувати деякі завдання щодня у визначену годину, інші лише щомісяця тощо). Для кожного завдання ви можете просто вибрати кілька часто використовуваних варіантів ("раз на день", "раз на місяць" ...) або використовувати потужний синтаксис "linux crontab" для встановлення точних термінів. Ви навіть можете визначити часто використовувані параметри для прискорення налаштування сайту. ...
  • Змініть пріоритет / порядок виконання завдання. ...

Ви можете використовувати цей модуль, щоб мати більш тонкий контроль над тим, як працює ваш Cron, щоб допомогти вирішити проблему, що склалася з кешем. Зокрема, ви можете додати крюк до своїх функцій відновлення до cron, а потім, використовуючи Elysia cron, встановити ці операції відразу після операції очищення кешу.

Це також здається, що у вас можуть виникнути проблеми із запуском хронів, що часто призводить до того, що кеш занадто часто відтворюється. Якщо це так, ви можете встановити певну операцію очищення кешу в Elysia cron, щоб вона виконувалась з іншою швидкістю, ніж у решті ваших операцій із керуванням, тому, наприклад, індексація пошуку оновлюватиметься кожні 5 хвилин, але повне очищення кешу виконуватиметься лише кожні 6 годин тощо.

Тонка настройка кеш-керового керування: drupal cron виводить з ладу змінний кеш кожного запуску, і це велика проблема продуктивності, якщо у вас є завдання, яке часто називають. Elysia cron оптимізує кеш-керування, і не потрібно скасовувати кеш.


Ну це справжній облом. Поспішайте D8! Власне, у мене, як я вже казав, є крон з elysia_cron, що працює щохвилини, гріючи те, що мені потрібно. Але оскільки мій сайт матиме> 10 000 / відвідувань / годину, я майже впевнений, що sbdy потрапить на порожні кеші ... Але все одно, я знаю, що це обмеження D7!
Григорій Капустін

12

Спосіб зробити це - використовувати hook_flush_cachesв поєднанні з register_shutdown_function. Приклад коду:

/**
 * Implements hook_flush_caches().
 */
function mymodule_flush_caches() {
   // After caches are cleared we will run mymodule_cache_rebuild()
   register_shutdown_function('mymodule_cache_rebuild');

   // We don't want to add any custom cache-tables, so just return an empty array
   return array();
}

/**
 * Rebuild expensive cache items that need to be rebuilt immediately.
 */
function mymodule_cache_rebuild() {
  // Do the cache rebuild work here
}

Використання register_shutdown_functionозначає, що наша функція відновлення кешу буде викликана після очищення кеш-пам'яті . Ми зловживаємо hook_flush_cachesтаким чином, щоб його ніколи не планували використовувати, але це має робити саме те, що потрібно.


Мені дуже подобається таке рішення. Перш ніж сам користуватися ним, я шукав будь-які відомі проблеми / конфлікти, що використовуються register_shutdown_function()в Drupal, і натрапив на Drupal ядро drupal_register_shutdown_function () : "Обгортка для register_shutdown_function (), яка вловлює викинуті винятки, щоб уникнути" Виняток, викинутий без кадру стека в Невідомо " . I знайте, це змушує мене почувати себе краще, abusing hook_flush_cachesякщо для цього я використовую лише основні функції Drupal.
runwithscissors

11

Ні, немає. Не зовсім. Принаймні, не в 6 або 7. Припускаючи 7:

Якщо ви подивитесь, drupal_flush_all_caches()ви побачите, що це викликає hook_flush_caches(). Цей гачок призначений для:

"додати назви таблиць кешу до списку таблиць кешу, які будуть очищені кнопкою" Очистити "на сторінці" Ефективність "або коли буде викликано drupal_flush_all_caches."

Було б заманливо просто змусити гачок вашого модуля останньою і написати там код. Але давайте ще раз подивимось drupal_flush_all_caches(). Фактичне видалення відбувається так:

  $cache_tables = array_merge(module_invoke_all('flush_caches'), $core);
  foreach ($cache_tables as $table) {
    cache_clear_all('*', $table, TRUE);
  }

Це означає, що всі гачки вистрілюються перед тим, як щось дійсно очиститься. Існує тільки одна функція , яка викликається після фактичного видалення, _system_update_bootstrap_status(), але це тільки дзвінки hook_boot, hook_exit, hook_watchdogі hook_language_init- перехоплює ви не хочете , щоб реалізувати тільки забезпечити кеш-ясно-залежну функціональність.


Чорт, мені потрібно було багато часу, щоб додати всі ці посилання;) Залишаю її поки що, оскільки я не можу змусити себе видалити її після стільки часу, витраченого на пояснення, чому цього не можна зробити.
Молото

3
Залиште, це хороша відповідь.
mpdonadio

Так, залиште, я не можу перевірити всі гарні відповіді, але я це зробив :)
Григорій Капустін

8

Широкі штрихи тут:

Хоча там не існує гачка в до-D8, ви можете написати власний сервер бази даних на основі стандартного, DrupalDatabaseCacheа потім записати будь-яку або всіляку логіку у свою clear()функцію. Швидкий погляд дозволить зробити це досить зрозумілим у D7 (просто скопіюйте клас у своє власне ім’я та змініть його тощо, додавши у module_invoke_all()відповідний спосіб), а модуль cache_backport навіть працюватиме в D6. Тоді вкажіть на будь-які ящики кешу, які ви хочете, щоб було вигадано, і ви повинні бути на шляху.


3
Це, мабуть, найкраще рішення, лише «проблема» полягає в тому, що якщо у вас є кілька кеш-файлів (memcache, redis тощо), вам доведеться розширити кілька класів кешу. Ще варто, хоча
Клайв

Не працюватиме з кешем у memcached, apc чи іншому не-db-рішенні, чи не так?
Молото

Я використовую Redis, не впевнений, що це спрацює.
Григорій Капустін

Якщо ви використовуєте drupal.org/project/redis, ви повинні мати можливість просто скопіювати або іншим чином змінити надані класи тощо у спеціальному модулі, а потім використовувати їх замість цього. Якщо ви щось використовуєте в рамках платформи Pantheon, де вони забезпечують важкий підйом для переробки, то так, вам знадобиться узгодити з ними про все це.
Jimajamma

3

Якщо ви подивитесь на джерело для drupal_flush_all_caches()та clear_cache_all(), то побачите, що жодних гачків не викликається після очищення, що є гарним клопом про помилку.

Дуже важко гарантувати, що користувачеві ніколи не доведеться чекати, коли будуть створені деякі записи кешу, тому я намагаюся максимально уникати очищення повного кешу.

Один із способів, який дійсно допомагає, - це змінити сторінку продуктивності, щоб підключити обробник подачі, який просто очищає кеші, спрямовані вперед, і не торкається меню, реєстру тощо. У мене були хороші результати з цього питання, оскільки відновлення меню та реєстру займає близько половини часу для повної відновлення кешу.

Інша річ, що у мене є сценарій барабану, який робить а drupal_http_request()на всіх моїх URL-адресах (не тільки важливих), щоб все було кешовано. Як це робиться, залежить від сайту. Іноді я можу просто EFQ опублікованих вузлів і створити URL-адреси таким чином. В іншому випадку ви можете запитувати таблиці XML мапи сайту, щоб отримати вашу URL-адресу. Потім я називаю це зі свого системного крона так часто, як мені потрібно.


1

Пара варіантів:
https://www.drupal.org/project/cache_graceful може бути саме тим, що ви хочете.

https://www.drupal.org/project/apdqc має 2 гачки, які вистрілюють у кеш-пам’яті, що дозволяє вам змінювати прозоре drupal_alter('apdqc_cache_clear', $cid, $wildcard, $this->bin, $caller);і після того, як дозволяє реагувати на очищення module_invoke_all('apdqc_cache_clear', $cid, $wildcard, $this->bin, $caller);. Переконайтеся, що APDQC працює правильно, і встановіть його $conf['apdqc_call_hook_on_clear'] = TRUE;у файл settings.php, і тоді гачки потрібно викликати, коли буде зроблено очищення кешу.


1

Це може підходити не для всіх і може бути недостатньо швидким для проведення ОП - оскільки це запускається лише на ініціалізації наступної сторінки. Однак мені це допомогло запустити код відразу після "кешу очистити все", який не був чутливим до часу.

Очевидно, що HOOKпотрібно замінити власне ім'я модуля.

/**
 * Implements hook_init().
 */
function HOOK_init(){
  // if there is no cache_not_empty defined, define it 
  // and then trigger our cache cleared code
  if ( !cache_get('HOOK_cache_not_empty') ) {
    cache_set('HOOK_cache_not_empty', TRUE);
    foreach (module_implements('cache_cleared') as $module) {
      module_invoke($module, 'cache_cleared');
    }
  }
}

/**
 * Implements hook_cache_cleared().
 */
function HOOK_cache_cleared(){
  // do what you need here, in which ever module.
}

Якщо у вас є певна скринька, на яку потрібно націлити, вищезгадане може бути змінено, щоб підтримати це, доки весь контейнер не буде випорожнено в точці кешу.

hook_initвиконується лише для не кешованих сторінок. Хоча повне очищення кешу повинно означати відсутність кешованих сторінок, це не повинно викликати проблем. Однак зовнішні системи кешування, такі як Varnish, перешкоджають цьому запуску, і це означає, що це відбудеться лише тоді, коли наступний належний запит повернеться до Drupal.

Слід також зазначити, що залежно від вашої системи кешування - коли саме вона cache_setстає доступною для всіх одночасних користувачів - цей гачок може бути спровокований кілька разів одночасно, особливо якщо у вас є велика кількість користувачів.


0

У мене була подібна потреба, коли клієнт хотів очистити кеші Drupal та Varnish, коли натиснув кнопку "промити всі кеші". Я викрав цей пункт меню, щоб зробити це.

Це не вплине на очищення кешу на кроні чи деінде - лише за посиланням на меню.

/**
 * Implements hook_menu_alter().
 */
function mymodule_menu_alter(&$items) {
  if (isset($items['admin_menu/flush-cache'])) {
    $items['admin_menu/flush-cache']['page callback'] =
      "_mymodule_custom_flush_cache";
  }
}

/**
 * Hijacks the "flush all caches" button in menu
 */
function _mymodule_custom_flush_cache() {
  /**
   * Clear varnish, or other logic here
   */
  admin_menu_flush_cache(); //Run the normal cache clearing stuff
}

Thx Travis, але я шукаю спосіб, який зачепить будь-яке чітке кешування, не тільки те, яке користувачеві викликає волонтер.
Григорій Капустін

0

Ви можете спробувати https://www.drupal.org/project/recacher - він використовує модуль Cache Expiration для виявлення прострочених сторінок, а потім повторно кешує лише ті сторінки, використовуючи відмінний HTTPRL.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.