재귀

2010-01-03 6 views
6

이 같은 장고 캐시에서 단일 경로를 삭제하고 장고 캐시에서 경로를 무효화 :재귀

from models     import Graph 
from django.http    import HttpRequest 
from django.utils.cache  import get_cache_key 
from django.db.models.signals import post_save 
from django.core.cache  import cache 

def expire_page(path): 
    request  = HttpRequest() 
    request.path = path 
    key   = get_cache_key(request) 
    if cache.has_key(key): 
     cache.delete(key) 

def invalidate_cache(sender, instance, **kwargs): 
    expire_page(instance.get_absolute_url()) 

post_save.connect(invalidate_cache, sender = Graph) 

이 작동 -하지만 반복적으로 삭제하는 방법이? 내 경로는 다음과 같습니다 :

/graph/123 
/graph/123/2009-08-01/2009-10-21 

은 때마다 ID로 그래프 "123"저장되고, 두 경로에 대한 캐시 무효화 될 필요가있다. 이 작업을 수행 할 수 있습니까?

+0

잘 모르겠 으면 귀하의 질문을 이해하면 올바른지, 당신은 모든 캐시를 내리고 싶다는 뜻 이겠지요 "123"이라는 ID를 가지고 있습니까? – Prashanth

+0

'/ graph/123 /'로 시작하는 경로의 캐시를 비우고 싶습니다. – knipknap

+0

나는 왜 당신이 경로에 대해 걱정하고 있는지 이해하지 못합니까? – Prashanth

답변

10

세대 별 캐싱 전략을 고려해 볼 수 있습니다. 달성하려는 목표에 맞을 것으로 보입니다. 제공 한 코드에서 각 절대 URL에 대해 "세대"번호를 저장합니다. 예를 들어, "/ graph/123"을 초기화하여 1 세대를 생성하면 캐시 키는 "/ GENERATION/1/graph/123"이됩니다. 해당 절대 URL에 대한 캐시를 만료 시키려면 생성 값을 증가시킵니다 (이 경우 2). 그렇게하면 다음에 누군가가 "/ graph/123"을 찾아가 캐시 키가 "/ GENERATION/2/graph/123"이됩니다. 또한 "/ graph/123"과 동일한 캐시 키를 참조해야하므로 모든 하위 페이지가 만료되는 문제도 해결됩니다.

처음에는 이해하기가 약간 까다 롭지 만, 올바르게 완료 되었다면 실제로 캐시에서 아무 것도 삭제할 필요가 없다는 것을 의미하는 매우 우아한 캐싱 전략입니다. 더 많은 정보는 여기 a presentation on generational caching, 그 레일에 대한 개념은 언어에 관계없이 동일합니다.

+0

그래서'/ graph/123'의 캐시 키가 항상 존재할 것이며'/ gen/1/graph/123' 또는'/ gen/2/graph/123' 등의 내용을 포함한다고 말할 것입니다. 그래서 앱은 먼저'/ graph/123'을 쿼리하여 가장 최근의 생성 키의 키를 얻은 다음'/ gen/x/graph/123'를 사용하여 캐쉬를 다시 쿼리하여 가장 최근의 캐싱 된 컨텐트를 얻습니다. 캐시 키가 항상 새로운 세대로 변경되는 경우 앱이 캐시를 쿼리하기 때문에 앱이 캐시를 어떻게 쿼리하기 때문에 까다로운 부분입니다. – raffian

-1

체크 아웃 shutils.rmtree() 또는 os.removedirs(). 나는 첫 번째가 아마 당신이 원하는 것이라고 생각합니다. 여러 의견에 따라

업데이트 : 사실, 장고 캐싱 메커니즘은 더 일반적이고 세분화 (당신이 그 수준에서 사용할 수 있지만) 그냥 키의 path을 사용하는 것보다. 우리는 범위의 기준에 따라 만료되는 별도로 캐시 된 7 개 또는 8 개의 하위 구성 요소가있는 페이지가 있습니다. 우리의 구성 요소 캐시 이름은 주요 개체 (또는 개체 클래스)를 반영하며 특정 업데이트에서 무효화해야 할 대상을 식별하는 데 사용됩니다.

Google의 모든 페이지에는 회원/비회원 상태에 따라 전체 캐시 키가 있지만 이는 페이지의 약 95 %에 불과합니다. 나머지 5 %는 회원 단위로 변경할 수 있으므로 전혀 캐시되지 않습니다.

캐시를 통해 반복하여 잘못된 항목을 찾는 방법은 실제로 저장되는 방식에 따라 달라집니다. 파일이라면 단순히 글로브 및/또는 재귀 적 디렉토리 삭제를 사용할 수 있습니다. 다른 메커니즘이라면 다른 것을 사용해야 할 것입니다.

내 대답과 다른 사람들의 의견 중 일부는 캐시 무효화를 수행하는 방법이 캐시 사용/저장 방법과 밀접하게 연관되어 있다는 것입니다.

두 번째 업데이트 : @andybak : 내 의견을 말씀드립니다. 제 상업적인 장고 사이트는 모두 화염으로 폭발 할 것입니다. 머리를 주셔서 감사합니다. 나는 당신이 문제에 대한 해답을 시도하지 않았 음을 확인합니다.

Knipknap의 문제는 그가 관련 때문에 자신의 이름의 계층 구조에 있지만, 캐시 메커니즘의 핵심 세대 로직의 MD5 해시를 생성하여 그 이름을 말살 한 것으로 나타났습니다 캐시 항목의 그룹을 가지고 있다는 것입니다 경로 + vary_on. 원래 경로/매개 변수의 흔적이 없으므로 모든 경로/매개 변수 조합을 철저히 추측해야합니다. 올바른 그룹을 찾을 수 있기를 바랍니다. 나는 다른 취미가 더 재미 있습니다.

당신은 경로 및/또는 매개 변수 값을 당신에게 패턴이 직접 또는이 정보를 보유하고 일부 시스템을 일치시킬 수 해야 중 하나를 사용하는 캐시 키의 조합을 기반으로 캐시 항목의 그룹을 찾을 수하고자하는 경우 검색 할 때 사용합니다.

우리는 OP 문제와 관련이 없기 때문에 2 년 전에 템플릿 조각 캐싱 (특히 키 생성)을 제어했습니다. 이를 통해 여러 가지 방식으로 regexps를 사용하여 관련된 캐시 된 항목 그룹을 효율적으로 무효화 할 수 있습니다.settings.py으로 구성 할 수있는 기본 시간 초과 및 vary_on 변수 이름 (런타임에 해결됨)을 추가하고 이름을 &으로 변경했습니다. 왜냐하면 fragment_name의 이름을 지정하기 위해 기본 시간 초과를 항상 무시해야한다는 의미가 없기 때문입니다. 다중 레벨 템플릿 상속 체계 및 여러 다른 것들로 더 잘 작동 할 수 있습니다 (즉, 변수가 될 수 있음).

처음 장황한 대답에 대한 유일한 이유는 이전 장고에서 잘못되었습니다. 왜냐하면 오래 동안 saner 캐시 키를 사용하여 문자 그대로 우리가 떠난 간단한 메커니즘을 잊어 버렸기 때문입니다.

+0

아니 * 꽤 * 내가 무슨 뜻인지. 그래도 고마워. – knipknap

+0

그럼, 좀 더 구체적으로 설명해야합니다. 캐시는 어디에 있습니까? 파일? memcached? 데이터 베이스? 그들이 파일에 있다면, 내 대답은 올바른 방향입니다. 그들이 다른 곳에 있으면 수정 된 객체를 포함하는 캐시 된 모든 항목을 일치시키는 메커니즘이 필요합니다. 우리는 우리 자신의 캐싱 메커니즘을 구현하여이 문제 (및 다른 여러 가지 캐시 무효화 문제)를 해결했습니다. 그렇게하기가 어렵지 않습니다. –

+0

downvote 유감스럽게 생각하지만 원래 질문은 Django를 사용하는 모든 사람에게 분명했습니다. –

1

또 다른 옵션은 태그 키를 지원하고 태그별로 키를 제거하는 캐시를 사용하는 것입니다. Django의 내장 캐시 API는이 접근법을 지원하지 않습니다. 하지만 적어도 하나의 캐시 백엔드 (Django의 일부는 아님)가 지원합니다.

DiskCache *는 순수 Python으로 작성되었으며 Django와 호환되는 Apache2 라이센스 디스크 및 파일 백업 캐시 라이브러리입니다. 프로젝트에서 DiskCache를 사용하려면 간단히 설치하고 CACHES 설정을 구성하십시오.

설치 pip로 쉽게 :

$ pip install diskcache 

는 그런 다음 CACHES 설정을 구성합니다

CACHES = { 
    'default': { 
     'BACKEND': 'diskcache.DjangoCache', 
     'LOCATION': '/tmp/path/to/directory/', 
    } 
} 

set 방법과 같이 옵션 tag 키워드 인수에 의해 확장 캐시 :

from django.core.cache import cache 

cache.set('/graph/123', value, tag='/graph/123') 
cache.set('/graph/123/2009-08-01/2009-10-21', other_value, tag='/graph/123') 

diskcache.DjangoCache은 내부적으로 diskcache.FanoutCache을 사용합니다. 해당 FanoutCache는 _cache 특성을 통해 액세스 할 수 있으며 evict 메서드를 노출합니다. 단순히 /graph/123 태그 모든 키를 퇴거 :

cache._cache.evict('/graph/123') 

를가 밑줄 - 접두사 속성에 액세스 할 수 어색하게 느낄 수 있지만, DiskCache 프로젝트는 안정과 DjangoCache 구현에 큰 변화를 만들 않을 수 있습니다.

Django cache benchmarks 페이지에는 대체 캐시 백엔드에 대한 설명이 있습니다.

  • 면책 조항 : 저는 DiskCache 프로젝트의 원작자입니다.