사용자 지정 캐싱 구현을위한 모범 사례?


17

모든 유형의 엔티티의 모든 인스턴스에 대해 다음과 같은 이름의 여러 캐시를 생성합니다. [module_name]__[entity_type]__[entity_id]__[string_depending_on_where_the_cache_came_from]

이제 엔티티가 업데이트 될 때마다 관련 엔티티 유형 및 ID로 시작하는 모든 캐시를 삭제하려고합니다.

이 캐시를 어떻게 저장 / 삭제해야합니까?

현재 나는 cache_set () 이지만 모든 관련 캐시의 이름을 모르기 때문에 지우고 싶을 때 문제가 발생합니다. db_delete ()로 캐시 항목을 삭제하는 것이 안전합니까?


모든 관련 캐시의 이름을 모른다면 어떻게 사용할 수 db_delete()있습니까?
kiamlaluno

답변:


6

캐시에서 항목을 삭제하려면 cache_clear_all () 을 사용해야합니다 . 사용 된 캐시 구현이 활성 데이터베이스에서 데이터베이스 테이블을 사용할 수 없기 때문입니다. 이것이 DrupalDatabaseCache 클래스에서 일어나는 일 이지만 모든 클래스에 해당되는 것은 아닙니다.

_cache_get_object () ( cache_get ()cache_set ()에 의해 호출되는 함수 ) 를 보면 다음 코드가 포함되어 있음을 알 수 있습니다.

  static $cache_objects; 
  if (!isset($cache_objects[$bin])) {
    $class = variable_get('cache_class_' . $bin);
    if (!isset($class)) {
      $class = variable_get('cache_default_class', 'DrupalDatabaseCache');
    }
    $cache_objects[$bin] = new $class($bin);
  }
  return $cache_objects[$bin];

캐시 구현의 클래스는 각 캐시 저장소마다 다를 수 있으며 기본 클래스도 변경 될 수 있습니다.

개인 업데이트 상태 캐시 시스템 은 일반 캐시 함수가 _update_cache_clear () , _update_cache_get ()_update_cache_set () 에서 사용되지 않는 이유를 정확하게 설명합니다 . (공포는 내 꺼야)

특히 사용 가능한 업데이트에 대한 페치 된 데이터를 저장하기 위해 코어 캐시 API를 사용하지 않습니다. 사용 가능한 새 업데이트 데이터를 성공적으로 가져온 후 캐시를 채우는 경우에만이 캐시를 지우는 것이 매우 중요합니다. 코어 캐시 API를 사용하면 사이트에 "최소 및 최대 둘 다"정의 된 사이트가있는 경우를 포함하여 항상 사용 가능한 업데이트 데이터를 가져 오려는 모든 종류의 잠재적 문제가 발생합니다. 또는 사이트가 memcache 또는 휘발성 캐시를 가정하는 다른 플러그 가능 캐시 시스템을 사용하는 경우.

업데이트 관리자 모듈은 여전히 {CACHE_UPDATE} 테이블을 사용하지만, 대신에 사용하여 cache_set(), cache_get()그리고 cache_clear_all()거기에이 같은 기본 작업을 구현하지만 캐시가 너무 빨리 삭제되지 않도록 개인 도우미 기능, 그리고 데이터가 항상 저장되어, memcache 또는 다른 캐시 백엔드가 사용중인 경우에도

업데이트 관리자가 업데이트 정보를 너무 자주 가져 오려고하면 Drupal.org 서버에 문제가 발생할 수 있습니다. 업데이트 관리자가 Drupal을 실행하는 모든 사이트에서 업데이트 정보를 가져올 수 있다는 점을 고려하면 Update Manager에는 필요한 특정 요구 사항이 있습니다.

귀하의 경우 [module_name]__[entity_type]__[entity_id]__[string_depending_on_where_the_cache_came_from]단일 캐시 저장소에 대한 캐시 ID로 사용할 수 있습니다 . 엔터티에 대한 모든 항목을 삭제해야하는 경우 다음 코드를 사용할 수 있습니다.

cache_clear_all("{$module}__{$entity_type}__{$entity_id}__", $bin, TRUE);

당신이에 할당 할 값을 얻을 수없는 경우 $module캐시를 삭제하는, 또는 데이터가 캐시되어있는 모듈에서 독립적으로 캐시 항목을 삭제하고자 할 때를, 다음과 같은 다른 캐시 ID를 사용할 수 있습니다 [entity_type]__[entity_id]__[string_depending_on_where_the_cache_came_from], 또는 [entity_type]__[entity_id]__[module_name]__[string_depending_on_where_the_cache_came_from]. is cache_clear_all()로 전달되는 문자열로 시작 하고 캐시 ID가 아닌 캐시 ID로 모든 캐시 항목을 삭제합니다 . 이 경우 캐시는 다음 코드로 지워집니다.$wildcardTRUE'*'

cache_clear_all("{$entity_type}__{$entity_id}__", $bin, TRUE);

8

항목을 수동으로 삭제하면 문제가 발생하는 좋은 이유를 생각할 수 없습니다. 물론 이것은 특정 캐시의 백엔드로 MySQL을 사용한다고 가정합니다. 다른 유형의 캐시 백엔드에도 동일하게 적용되지만 데이터베이스를 지우는 방법은 데이터베이스 쿼리 일 필요는 없습니다.

코어 업데이트 모듈을 예로 들면, cache_*기능을 무시 하고 캐시를 수동으로 지 웁니다.

function _update_cache_clear($cid = NULL, $wildcard = FALSE) {
  if (empty($cid)) {
    db_delete('cache_update')
      // Clear everything except fetch task information because these are used
      // to ensure that the fetch task queue items are not added multiple times.
      ->condition('cid', 'fetch_task::%', 'NOT LIKE')
      ->execute();
  }
  else {
    $query = db_delete('cache_update');
    if ($wildcard) {
      $query->condition('cid', $cid . '%', 'LIKE');
    }
    else {
      $query->condition('cid', $cid);
    }
    $query->execute();
  }
}

나는 항상 "핵심에 충분하다면 나에게 충분하다"고 생각합니다. :)

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