Django配置缓存机制

作者: 緣來 | 来源:发表于2018-08-28 00:04 被阅读147次

    Django 官方关于cache的介绍:https://docs.djangoproject.com/en/dev/topics/cache/

    Django 是动态网站,一般来说需要实时地生成访问的网页,展示给访问者,这样,内容可以随时变化,但是从数据库读多次把所需要的数据取出来,要比从内存或者硬盘等一次读出来 付出的成本大很多。而使用缓存的话,可以将数据保存在缓存中,下次访问的时候直接从缓存中获得数据,而不用去请求后端数据库,这样服务器可以很快的响应请求,从而提高加载速度。

    缓存系统工作原理:

    对于给定的网址,尝试从缓存中找到网址,如果页面在缓存中,直接返回缓存的页面,如果缓存中没有,一系列操作(比如查数据库)后,保存生成的页面内容到缓存系统以供下一次使用,然后返回生成的页面内容。

    一般来说我们用 Django 来搭建一个网站,要用到数据库等。

    from django.shortcuts import render
    def index(request):
        # 读取数据库等 并渲染到网页
        # 数据库获取的结果保存到 queryset 中
        return render(request, 'index.html', {'queryset':queryset})
    

    像这样每次访问都要读取数据库,一般的小网站没什么问题,当访问量非常大的时候,就会有很多次的数据库查询,肯定会造成访问速度变慢,服务器资源占用较多等问题。

    from django.shortcuts import render
    from django.views.decorators.cache import cache_page
     
    @cache_page(60 * 15) # 秒数,这里指缓存 15 分钟,不直接写900是为了提高可读性
    def index(request):
        # 读取数据库等 并渲染到网页
        return render(request, 'index.html', {'queryset':queryset})
    

    当使用了cache后,访问情况变成了如下:

    # 访问一个网址时, 尝试从 cache 中找有没有缓存内容
    # 如果网页在缓存中显示缓存内容,否则生成访问的页面,保存在缓存中以便下次使用,显示缓存的页面。
    given a URL, try finding that page in the cache
    if the page is in the cache:
        return the cached page
    else:
        generate the page
        save the generated page in the cache (for next time)
        return the generated page
    

    Django settings 中 cache 默认为

    {
        'default': {
            'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        }
    }
    

    也就是默认利用本地的内存来当缓存,速度很快。当然可能出来内存不够用的情况,其它的一些内建可用的 Backends 有

    'django.core.cache.backends.db.DatabaseCache'
    'django.core.cache.backends.dummy.DummyCache'
    'django.core.cache.backends.filebased.FileBasedCache'
    'django.core.cache.backends.locmem.LocMemCache'
    'django.core.cache.backends.memcached.MemcachedCache'
    'django.core.cache.backends.memcached.PyLibMCCache'
    

    在 github 上也有用 redis 做 Django的缓存系统的开源项目:https://github.com/niwibe/django-redis,有兴趣的可以看看哦!

    下面我们就来介绍一下各种缓存的配置:

    缓存配置

    利用文件系统来缓存:

    这个很简单,就是将数据缓存在指定的目录中。配置如下:

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
            'LOCATION': '/var/tmp/django_cache',
            'TIMEOUT': 600,
            'OPTIONS': {
                'MAX_ENTRIES': 1000
            }
        }
    }
    

    利用数据库来缓存:

    利用命令创建相应的表:

    $ python manage.py createcachetable my_cache_table
    

    配置如下所示:

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
            'LOCATION': 'my_cache_table',
            'TIMEOUT': 600,
            'OPTIONS': {
                'MAX_ENTRIES': 2000
            }
        }
    }
    

    使用Memcache来缓存:

    Memcached 是目前 Django 可用的最快的缓存,

    但是memcache需要你的服务器支持,也就是说需要有Memcache服务,

    Linux系统安装Memcached,首先要先安装libevent库。

    $ sudo apt-get install libevent ibevent-dev         自动下载安装(Ubuntu/Debian)
    
    $ yum install libevent libevent-devel                    自动下载安装(Redhat/Fedora/Centos)
    

    接着使用命令安装Memcache服务:

    Ubuntu/Debian

    $ sudo apt-get install memcached
    

    Redhat/Fedora/Centos

    $ yum install memcached
    

    然后需要pip安装Memcached的插件Python-mencached和pylibmc

    $ pip install Python-mencached
    $ pip install pylibmc
    

    最后在setting.py配置:

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': '127.0.0.1:11211',
            'TIMEOUT': 600,
            'OPTIONS': {
                'MAX_ENTRIES': 2000
            }
        }
    }
    

    使用Local-memory来缓存:

    这种缓存方式会将数据保存在服务器的内存中。

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
            'LOCATION': 'unique-snowflake',
            'TIMEOUT': 600,
            'OPTIONS': {
                'MAX_ENTRIES': 2000
            }
        }
    }
    

    最推荐的缓存方式是Memcache或者Local-memory,要不就是文件缓存,最不推荐的是数据库缓存。

    下面用一些实例来说明如何使用 Django 缓存系统

    使用 Django 缓存系统

    全站缓存

    这种方式最简单最容易配置了,就是将你全站都做缓存,所有的页面都会缓存下来,配置方式: 在setting.pyMIDDLEWARE中添加:

    MIDDLEWARE = [
        'django.middleware.cache.UpdateCacheMiddleware',
        'django.middleware.common.CommonMiddleware',
        'django.middleware.cache.FetchFromCacheMiddleware',
    ]
    

    也就是将django.middleware.cache.UpdateCacheMiddlewaredjango.middleware.cache.FetchFromCacheMiddleware分别添加在django.middleware.common.CommonMiddleware的前面和后面,注意,顺序不能反过来。 这种方式清除缓存的话使用:

    from django.core.cache import cache
    cache.clear()
    

    视图缓存

    这种方式会指定要缓存的视图,只会缓存这个视图,

    from django.views.decorators.cache import cache_page
    
    @cache_page(60 * 15, key_prefix="site1")
    def my_view(request):
        ...
    

    cache_page的参数分别是缓存过期时间以及缓存key的前缀。 也可以在路由url.py中指定要缓存的页面:

    from django.views.decorators.cache import cache_page
    
    urlpatterns = [
        url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)),
        #也可以这样,如果你的视图是classbase的话:
        url(r'^$', cache_page(60 * 60 * 10, key_prefix="blogindex")(views.IndexView.as_view()), name='index'),
    ]
    

    如果你的视图是class base的话,可以这样使用缓存:

    from django.utils.decorators import method_decorator
    from django.views.decorators.cache import cache_page
    from django.views.generic import ListView
    
    @method_decorator(cache_page(60*60), name='dispatch')
    class MyListView(ListView):
        # Your view code here.
    

    视图缓存的清除方式:

    在django中可以使用cache_page的方式来缓存视图,但是如何删除指定视图的缓存呢?在文档中没找到清除的方式,但是在Google的时候找到了解决方案,我自己本地测试可以使用,不确定将来的版本会不会无效,下面先介绍下解决办法:

    核心功能是这些:

    def expire_view_cache(path, servername, serverport, key_prefix=None):
        from django.http import HttpRequest
        from django.utils.cache import get_cache_key
    
        request = HttpRequest()
        request.META = {'SERVER_NAME': servername, 'SERVER_PORT': serverport}
        request.path = path
    
        key = get_cache_key(request, key_prefix=key_prefix, cache=cache)
        if key:
            if cache.get(key):
                cache.delete(key)
            return True
        return False
    

    其实就是构造一个HttpRequest对象,然后调用Django内部的get_cache_key来获得缓存key。 调用方式:

    #site也可以直接指定,也就是当前站点的domain name
    from django.contrib.sites.models import Site
    site = Site.objects.get_current().domain
    #path为要删除的视图缓存的路径,key_prefix为使用cache_page时指定的key_prefix
    expire_view_cache(path, servername=site, serverport=port, key_prefix='blogdetail')
    

    模版缓存

    当然,也可以直接在模版中使用缓存

    {% load cache %}
    {% cache 500 sidebar request.user.username %}
        .. sidebar for logged in user ..
    {% endcache %}
    

    参数分别是过期时间,缓存名,区分不同缓存的参数 模版缓存的删除方式就简单多了,以上面的配置为例:

    from django.core.cache.utils import make_template_fragment_key
    from django.core.cache import cache
    username = self.request.user.username if self.request.user else ''
    key = make_template_fragment_key('sidebar', [username])
    cache.delete(key)
    

    此文章同时同步到我的个人博客緣來來來 » Django配置缓存机制

    相关文章

      网友评论

        本文标题:Django配置缓存机制

        本文链接:https://www.haomeiwen.com/subject/ytmxwftx.html