Django 缓存

简介

为什么要用缓存?

我们知道,在Django中,请求到达视图后,视图会从数据库取数据放到模板中进行动态渲染,渲染后的结果就是用户看到的html页面。但是,如果每次请求都从数据库取数据并渲染,将极大降低性能,不仅服务器压力大,而且客户端也无法即时获得响应。如果能将渲染后的结果放到速度更快的缓存中,每次有请求过来,先检查缓存中是否有对应的资源,如果有,直接从缓存中取出来返回响应,节省取数据和渲染的时间,不仅能大大提高系统性能,还能提高用户体验。

另外,缓存只是一类统称,一般其介质是速度很快的内存,但也可以是能加快数据读取的其它方式。

什么时候适合用缓存?

对页面实时性要求不高的页面,可以用缓存。比如博客文章,假设用户一天更新一篇文章,那么可以为博客设置1天的缓存;一天后会刷新。另外像购物网站,商品的描述信息几乎不会变化,而商品的库存数量却要求根据用户的购买实时更新,因此也应该应用合适的缓存策略。

缓存方式

Django中提供了6中缓存方式,如果要使用缓存,需要现在settings.py中进行配置,然后再应用。

配置

开发调试

开发调试实际不做缓存,这里不做赘述。

内存

 CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',
        'TIMEOUT': 300,  
        # 缓存超时时间(默认300,None表示永不过期,0表示立即过期)
        'OPTIONS':{
            'MAX_ENTRIES': 300,                                       
            # 最大缓存个数(默认300)
            'CULL_FREQUENCY': 3,                                      
            # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3);实际中一般不这么用,太简单粗暴了。
        }
    }
}

以上的'TIMEOUT'、'OPTIONS'项在下面的几种缓存配置中是通用的。

另外,我们也可以在setting.py中单独配置CACHE_MIDDLEWARE_SECONDS = 10缓存超时时间,其优先级高于CACHES中的TIMEOUT

内存缓存是当前机器的内存,不常用。

文件

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': 'D:\cache',
        }
}   

文件即硬盘缓存,小网站的低成本解决方案。

tips: 数据库连接是socket通信,速度不如本地文件快;而且数据库拿来的数据还要渲染,而文件中已经是渲染好的字符串,因此比起数据库还是要快。

数据库

CACHES = {
'default': {
    'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
    'LOCATION': 'my_cache_table', # 数据库表
    }
    # 执行创建表命令 python manage.py createcachetable
}

数据库缓存,存储的是渲染好的字符串,少了渲染这一步,稍微快一点。不常用。

Memcache缓存(python-memcached模块)

# 此缓存使用python-memcached模块连接memcache

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': '127.0.0.1:11211',
        }
    }

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': 'unix:/tmp/memcached.sock',
        }
    }   

    CACHES = {
        'default': {
            'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
            'LOCATION': [
                '172.19.26.240:11211',
                '172.19.26.242:11211',
            ]
            # 我们也可以给缓存机器加权重,权重高的承担更多的请求,如下
            'LOCATION': [
                ('172.19.26.240:11211',5),
                ('172.19.26.242:11211',1),
            ]
        }
    }

用一台具有超大内存的机器,安装Memcache或Redis软件,提供ip和端口,本机向其发送指令来存取数据,而且可以支持分布式存储。但是内存数据断电丢失,因此一般配置两台机器,各存一半的数据,即使挂了一台,还有一台分担数据库压力。一旦缓存都挂了,如果有大量请求直接到达数据库,可能会导致程序崩掉。

Memcache缓存(pylibmc模块)

用起来用上一种是一样的,只是实现用的模块不一样。配置时,将’BACKEND’: 的值改为'django.core.cache.backends.memcached.PyLibMCCache'就好了

应用

全站缓存:粒度大

全站缓存可以在中间件的最后一个来做,只有验证合法的请求,才允许返回响应。如果请求的资源有缓存,返回缓存作为响应体,通过中间件时再加上响应头返回给客户端。因为中间件可以对响应进行处理,甚至修改返回值,因此需要在出去时的最后一个中间件(即进来的时走的第一个中间件)给缓存。

但是Django中已经提供好了这两个中间件,我们直接加到setting.py中就可以了。

 MIDDLEWARE = [
        'django.middleware.cache.UpdateCacheMiddleware',
        # 其他中间件...
        'django.middleware.cache.FetchFromCacheMiddleware',
    ]

请求进来时,通过FetchFromCacheMiddleware获取资源,响应出去时,如果缓存中不存在请求的资源,则通过django.middleware.cache.UpdateCacheMiddleware将响应字符串保存在缓存中。

全站缓存适合实时性要求不高的网站,比如个人博客。

单独视图函数:粒度适中

这里,我们通过文件缓存的配置方式来实践缓存。

方式一:在视图上方加装饰器@cache_page(seconds)
from django.shortcuts import render
from time import ctime
from django.views.decorators.cache import cache_page


@cache_page(5)  # 这里设置5秒缓存超时
def test(request):
    """这里通过获取当前时间来模拟从数据库中取数据"""
    now = ctime()
    return render(request, 'test.html', {'now': now})
<!-- test.html -->
<body>

<h1>当前时间是:</h1>
<h3>{{ now }}</h3>

</body>

这样我们通过浏览器访问当前视图时,会获取到当前时间,但是当我们刷新页面,时间并不会变化,除非5秒后再刷新:

这里写图片描述

检查本地磁盘,发现生成了缓存文件:

2.png

方式二:在路由中进行配置
from django.views.decorators.cache import cache_page

urlpatterns = [
    url(r'^test.html/$', cache_page(5)(views.test)),
    # 将cache_page(5) 加到视图前面
]

局部模板:粒度小,更灵活

通过在模板中应用{% cache %}来进行局部缓存控制,还是上面的栗子,我们将模板简单改一下:

<!-- 引入TemplateTag -->
{% load cache %}

<body>
<h1>当前时间是:</h1>
<h3>{{ now }}</h3>

<h1>当前时间是(使用缓存):</h1>
{% cache 5 key %}
<h3>{{ now }}</h3>
{% endcache %}

<!-- 注意 cache 要求两个参数:seconds, key -->
</body>

重新访问页面,3秒后刷新以下,发现使用缓存的时间没有变化

3.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值