캐시 지우기에 연결하는 방법이 있습니까?


16

캐시가 많은 대형 기관 웹 사이트의 경우 가능한 한 빨리 캐시를 생성하여 사용자가 캐시 생성에 도달하지 못하게하고 싶습니다 ...

나는 크론 몇 가지 기능을 실행하고 중요한 페이지를 요청하여, 그것을 수행하는 모든 분을 설정,하지만 내가 무엇을 찾고있어입니다 캐시 그냥 삭제되었을 때 알 수있는 방법 내가 이것을 실행할 수 있도록, 바람직하게는 후크를 생성 기능.

어떤 아이디어?


수행하려는 작업에 따라 페이지를 아래로 내리는 phayes의 답변은 캐시가 지워진 후 코드를 해제하는 좋은 솔루션입니다.
레스터 피바디

답변:


7

Drupal 7.x에는 없지만 Drupal 8.x 의 핵심 훅 hook_rebuild 가 추가되었습니다 . 그래도 7.x에서 문제를 해결하는 더 좋은 방법이있을 수 있습니다. cron이 캐시를 지운 직후에 일종의 캐시 워밍 기능을 시작하려고합니다. 맞습니까? 이것에 접근하는 또 다른 방법은 cly 가 작동하는 방식이 크게 개선되었지만 사용 사례와 관련이있는 두 가지 Elysia cron 을 사용 하는 것입니다.

Elysia Cron은 Drupal 표준 cron을 확장하여 각 작업을 세부적으로 제어하고 사이트에 사용자 정의 cron 작업을 추가 할 수있는 몇 가지 방법을 제공합니다.

  • 각 cron 태스크의 타이밍 및 빈도를 설정하십시오 (매월 일부 작업은 지정된 시간에 수행 할 수 있고 다른 작업은 월 단위로만 수행 할 수 있습니다). 각 작업마다 자주 사용하는 옵션 ( "하루에 한 번", "한 달에 한 번"...)을 선택하거나 강력한 "리눅스 크론 탭"과 같은 구문을 사용하여 정확한 타이밍을 설정할 수 있습니다. 사이트 구성 속도를 높이기 위해 자주 사용하는 옵션을 정의 할 수도 있습니다. ...
  • 작업 실행의 우선 순위 / 순서를 변경하십시오. ...

이 모듈을 사용하면 오래된 캐시 문제를 해결하기 위해 cron 실행 방식을보다 세밀하게 제어 할 수 있습니다. 특히, cron에 재 빌드 기능에 대한 후크를 추가 한 다음 Elysia cron을 사용하여 캐시 지우기 조작 직후에 이들 조작이 실행되도록 설정할 수 있습니다.

또한 cron을 실행하는 데 문제가있어 캐시가 너무 자주 다시 생성되는 것처럼 들립니다. 이 경우 Elysia cron의 특정 캐시 지우기 작업을 나머지 cron 작업과 다른 속도로 실행하도록 설정할 수 있습니다. 예를 들어 검색 인덱싱은 5 분마다 업데이트되지만 전체 캐시 지우기는 매번 만 실행됩니다. 6 시간 등

크론 캐시 관리 미세 조정 : drupal cron은 모든 크론 실행시 변수 캐시를 무효화합니다. 자주 호출되는 작업이있는 경우 이는 큰 성능 문제입니다. Elysia cron은 캐시 관리를 최적화하며 캐시를 무효화 할 필요가 없습니다.


글쎄, 이것은 진짜 부머입니다. 서둘러 D8! 사실, 나는 이미 말했듯이 elysia_cron이있는 cron이 1 분마다 실행되어 필요한 것을 따뜻하게합니다. 그러나 내 사이트가> 10.000 / 방문 / 시간을 가짐에 따라 sbdy가 빈 캐시에 떨어질 것이라고 확신합니다 ... 어쨌든, 나는 그것이 D7 제한이라는 것을 알고 있습니다!
Gregory Kapustin

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 () : " Login register_shutdown_function ()에 대한 래퍼가 발생했습니다 . 그것이하게 알고 나를 더 나은에 대한 느낌이 abusing hook_flush_caches나는 그것을 할 만 드루팔 핵심 기능을 사용하고있는 경우.
runswithscissors

11

아닙니다. 실제로는 아닙니다. 적어도 6 또는 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_watchdoghook_language_init- 당신은 캐시 맑은 의존하는 기능을 제공하는 경우에만 구현하지 않으려는 후크.


젠장, 그것은 오래 이러한 모든 링크를 추가하라고했다) 나는 그것을 삭제 나 자신을 강제 할 수 없기 때문에 너무 많은 시간이 설명에 소요 된 후, 지금은 그것을 떠나 그것을 할 수 없습니다.
Mołot

3
그대로 두십시오. 좋은 대답입니다.
mpdonadio

네, 그대로 두세요. 모든 정답을 확인할 수는 없지만
Gregory Kapustin

8

광범위한 스트로크 :

D8 이전에는 훅이 없지만 표준 데이터베이스를 기반으로 자체 데이터베이스 백엔드 DrupalDatabaseCache를 작성한 다음 clear()함수 에 논리를 작성하십시오 . 간략히 살펴보면 D7에서이 클래스가 상당히 간단하다는 것을 알 수 있습니다 (클래스를 사용자 정의 이름으로 복사하고 module_invoke_all()적절하게 던져서 수정하는 등 ). 그리고 cache_backport 모듈을 사용 하면 D6에서도 작동합니다. 그런 다음 당신이 원하는 모든 캐시 빈을 비우고 당신이 가고 있어야합니다.


3
이것은 아마도 가장 좋은 해결책 일 것입니다. '문제점'은 여러 캐시 빈 (memcache, redis 등)이있는 경우 여러 캐시 클래스를 확장해야한다는 것입니다. 그래도 그만한 가치가 있습니다
Clive

memcached, apc 또는 기타 비 DB 솔루션의 캐시에서 작동하지 않습니까?
Mołot

Redis를 사용하지만 확실하지 않습니다.
Gregory Kapustin

drupal.org/project/redis 를 사용 하는 경우 사용자 정의 모듈에서 제공된 클래스 등을 복사하거나 수정 한 다음 대신 사용할 수 있어야합니다. 그러나 Pantheon 플랫폼의 라인을 따라 무언가를 사용하고 있다면 redis에 대한 모든 무거운 물건을 들어 올리면이 모든 것에 대해 그들과 협력해야합니다.
Jimajamma

3

drupal_flush_all_caches()and 의 소스를 살펴보면 clear_cache_all()삭제 후 호출 된 후크가 없다는 것을 알 수 있습니다.

사용자가 일부 캐시 항목이 빌드 될 때까지 기다릴 필요가 없다는 것을 보장하는 것은 매우 어렵 기 때문에 가능한 한 전체 캐시 지우기를 피하려고합니다.

실제로 도움이되는 한 가지 방법은 성능 페이지를 변경하여 전송 캐시를 지우고 메뉴, 레지스트리 및 유사한 코어 캐시를 건드리지 않는 제출 핸들러를 연결하는 것입니다. 메뉴와 레지스트리 재 구축이 전체 캐시 재 구축에 약 절반의 시간이 걸리므로 좋은 결과를 얻었습니다.

다른 drupal_http_request()하나는 중요한 URL뿐만 아니라 모든 URL에 대해 drush 스크립트를 사용 하여 모든 것이 캐시되도록하는 것입니다. 이 작업을 수행하는 방법은 사이트마다 다릅니다. 때로는 게시 된 노드를 EFQ하고 URL을 그렇게 만들 수도 있습니다. 다른 경우에는 URL을 얻기 위해 XML 사이트 맵 테이블을 쿼리 할 수 ​​있습니다. 그런 다음 필요할 때마다 시스템 크론에서 이것을 호출합니다.


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

다음 페이지 초기화시에만 트리거되므로 OP는 모든 사람에게 적합하지 않을 수도 있고 OP에 충분하지 않을 수도 있습니다. 그러나 시간이 중요하지 않은 "캐시 모두 지우기"직후에 코드를 트리거하는 데 도움이되었습니다.

분명히 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 캐시를 모두 플러시하려는 비슷한 요구가있었습니다. 나는 그 메뉴 항목을 가로 채었다.

이것은 메뉴 링크에서 cron이나 다른 곳에서 캐시를 지우지 않습니다.

/**
 * 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이지만 사용자가 자발적으로 트리거 한 것뿐만 아니라 명확한 캐싱을 연결하는 방법을 찾고 있습니다.
Gregory Kapustin

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.