2015-10-23 25 views
1

我一直认为每个站点的缓存不会更新,直到它到期,还有其他人thought so。但是我在我的网站上做了一些测试后发现了不同的结果。如你所见,My website是一个典型的博客。django每站点缓存如何正确工作?

以下是我测试过它:使用memcached -vv,让我可以看到在memcached中发生了什么

  1. 启动memcached的。 然后做了一些操作:

  2. 浏览网页 - >浏览网页 - >主页上更新了一篇文章 - >浏览网页
    缓存存储                 没有                                   没有                                                                                缓存存储(奇怪!)

首页在我上次访问确实更新。我的缓存过期时间为600秒,所以我可以向你保证第二次缓存存储操作与缓存过期无关(实际上我重复了几次,都给出了相同的结果)。

那么对此有何解释? documentaion没有提供太多的信息。还是因为我以错误的方式进行了测试?

+0

这是很难,而无需源代码来回答。也许memcached的-vv在删除密钥的情况下不起作用,因此“更新主页上的文章”会以静静的方式重新评估缓存。 –

+0

@SergeyMNikitin https://github.com/laike9m/My_Blog,源代码在这里。 – laike9m

+0

也请记住,该框架考虑相同的URL瓦特/不同的查询参数是不同的反应,将分别缓存每个。例如,即使内容完全相同,“/ blog /?page = 1”和“blog /”也会获得单独的缓存条目。你看到相同的缓存键吗? – bimsapi

回答

1

你可以看一下的process_response源代码中间件UpdateCacheMiddleware弄明白:

def process_response(self, request, response): 
    """Sets the cache, if needed.""" 
    if not self._should_update_cache(request, response): 
     # We don't need to update the cache, just return. 
     return response 

    if response.streaming or response.status_code != 200: 
     return response 

    # Don't cache responses that set a user-specific (and maybe security 
    # sensitive) cookie in response to a cookie-less request. 
    if not request.COOKIES and response.cookies and has_vary_header(response, 'Cookie'): 
     return response 

    # Try to get the timeout from the "max-age" section of the "Cache- 
    # Control" header before reverting to using the default cache_timeout 
    # length. 
    timeout = get_max_age(response) 
    if timeout is None: 
     timeout = self.cache_timeout 
    elif timeout == 0: 
     # max-age was set to 0, don't bother caching. 
     return response 
    patch_response_headers(response, timeout) 
    if timeout: 
     cache_key = learn_cache_key(request, response, timeout, self.key_prefix, cache=self.cache) 
     if hasattr(response, 'render') and callable(response.render): 
      response.add_post_render_callback(
       lambda r: self.cache.set(cache_key, r, timeout) 
      ) 
     else: 
      self.cache.set(cache_key, response, timeout) 
    return response 

首先检查你的博客的目的是有身份验证的用户,因为它是它不会因工作到if not request.COOKIES and response.cookies and has_vary_header(response, 'Cookie')

如果没有,那么验证你不得不考虑learn_cache_key方法,计算在该视图将被缓存的关键:

def learn_cache_key(request, response, cache_timeout=None, key_prefix=None, cache=None): 
""" 
Learns what headers to take into account for some request URL from the 
response object. It stores those headers in a global URL registry so that 
later access to that URL will know what headers to take into account 
without building the response object itself. The headers are named in the 
Vary header of the response, but we want to prevent response generation. 

The list of headers to use for cache key generation is stored in the same 
cache as the pages themselves. If the cache ages some data out of the 
cache, this just means that we have to build the response once to get at 
the Vary header and so at the list of headers to use for the cache key. 
""" 
if key_prefix is None: 
    key_prefix = settings.CACHE_MIDDLEWARE_KEY_PREFIX 
if cache_timeout is None: 
    cache_timeout = settings.CACHE_MIDDLEWARE_SECONDS 
cache_key = _generate_cache_header_key(key_prefix, request) 
if cache is None: 
    cache = caches[settings.CACHE_MIDDLEWARE_ALIAS] 
if response.has_header('Vary'): 
    is_accept_language_redundant = settings.USE_I18N or settings.USE_L10N 
    # If i18n or l10n are used, the generated cache key will be suffixed 
    # with the current locale. Adding the raw value of Accept-Language is 
    # redundant in that case and would result in storing the same content 
    # under multiple keys in the cache. See #18191 for details. 
    headerlist = [] 
    for header in cc_delim_re.split(response['Vary']): 
     header = header.upper().replace('-', '_') 
     if header == 'ACCEPT_LANGUAGE' and is_accept_language_redundant: 
      continue 
     headerlist.append('HTTP_' + header) 
    headerlist.sort() 
    cache.set(cache_key, headerlist, cache_timeout) 
    return _generate_cache_key(request, request.method, headerlist, key_prefix) 
else: 
    # if there is no Vary header, we still need a cache key 
    # for the request.build_absolute_uri() 
    cache.set(cache_key, [], cache_timeout) 
    return _generate_cache_key(request, request.method, [], key_prefix) 

注意,Django会深入到response['Vary']头,并添加到密钥变化到它的关键。

所以,先检查一下你的回复是否加了Vary头,如果是这样的值,如果它与保存条目之前的不同,你将会得到为什么没有被缓存。

还要注意的是,如果多语言被激活,它也将产生每种语言不同的密钥。

当Django添加或修改Vary头?

在这里,您可以看到它何时发生或如何发生在docs以及如何在视图here中控制缓存。

最后考虑到,如果您使用的是第三方应用为你的博客,那么它可能使用高速缓存控制机制,例如更新条目不同的数据时刷新缓存。

Django的版本

在Django中> = 1.7完全合格的URL中使用,所以如果你使用这些版本还考虑到HOSTS:

在Django 1.7更改: 缓存键使用请求的完全限定的URL而不仅仅是路径和查询字符串。

+0

我没有使用第三方应用程序。问题可能是通过不同的网址(laike9m.com和www.laike9m.com)访问。 – laike9m

+0

是的,这是我在帖子中给出的原因之一,事实上,在Django 1.7中,有一个关于URLS如何由每个站点缓存处理的警告(从1.7开始,它们完全合格) – danigosa

-1

好了,原来我的测试有问题。当没有人访问我的网站时,我再次仔细测试。下面是memcached -vv输出:

# first visit 

<30 new auto-negotiating client connection 
30: Client using the ascii protocol 
<30 get :1:views.decorators.cache.cache_header..f384b899ecab7abd6fb0a567608b97b2.en-us.CST 
>30 END 
<30 set :1:views.decorators.cache.cache_header..f384b899ecab7abd6fb0a567608b97b2.en-us.CST 1 600 14 
>30 STORED 
<30 set :1:views.decorators.cache.cache_page..GET.f384b899ecab7abd6fb0a567608b97b2.d41d8cd98f00b204e9800998ecf8427e.en-us.CST 1 600 33215 
>30 STORED 
<30 connection closed. 

# second visit 

<30 new auto-negotiating client connection 
30: Client using the ascii protocol 
<30 get :1:views.decorators.cache.cache_header..f384b899ecab7abd6fb0a567608b97b2.en-us.CST 
>30 sending key :1:views.decorators.cache.cache_header..f384b899ecab7abd6fb0a567608b97b2.en-us.CST 
>30 END 
<30 get :1:views.decorators.cache.cache_page..GET.f384b899ecab7abd6fb0a567608b97b2.d41d8cd98f00b204e9800998ecf8427e.en-us.CST 
>30 sending key :1:views.decorators.cache.cache_page..GET.f384b899ecab7abd6fb0a567608b97b2.d41d8cd98f00b204e9800998ecf8427e.en-us.CST 
>30 END 
<30 connection closed. 

# modified and save 

<30 new auto-negotiating client connection 
30: Client using the ascii protocol 
<30 get :1:views.decorators.cache.cache_header..7029e9375fc4657a73dae1f9bddb73e5.en-us.CST 
>30 END 
<30 connection closed. 

# visit again 

<30 new auto-negotiating client connection 
30: Client using the ascii protocol 
<30 get :1:views.decorators.cache.cache_header..f384b899ecab7abd6fb0a567608b97b2.en-us.CST 
>30 sending key :1:views.decorators.cache.cache_header..f384b899ecab7abd6fb0a567608b97b2.en-us.CST 
>30 END 
<30 get :1:views.decorators.cache.cache_page..GET.f384b899ecab7abd6fb0a567608b97b2.d41d8cd98f00b204e9800998ecf8427e.en-us.CST 
>30 sending key :1:views.decorators.cache.cache_page..GET.f384b899ecab7abd6fb0a567608b97b2.d41d8cd98f00b204e9800998ecf8427e.en-us.CST 
>30 END 
<30 connection closed. 

此输出显示Memcached是按预期工作。我不确定以前的输出是什么解释。