Django-Redis实现整站缓存

Django缓存存储方式

动态网站存在一个基本权衡是——它们是动态的。每次用户请求一个页面,web 服务器需要提供各种各样的计算——从数据库查询到模板渲染再到业务逻辑——最后建立页面呈现给用户。从处理开销的角度来看,这比标准读取文件系统服务安排的开销要高得多。Django 带有一个强大的缓存系统,我们可以将动态页面保存,这样不用每次请求页面时都计算。为方便起见,Django 提供了不同级别的缓存粒度:我们可以缓存特定视图,也可以只缓存难生成的部分内容,或者缓存整个网站。
Django提供多种缓存机制:比如Memcached缓存、Redis缓存(需要安装django-redis包)、数据库缓存、文件系统缓存、本地内存缓存、伪缓存(Dummy Cache,用于开发、测试)、自定义缓存等方式。Django的缓存策略也有多种:整站缓存、视图缓存、模板片段缓存等。详细内容大家可以参考官方文档:https://docs.djangoproject.com/zh-hans/2.2/topics/cache/

Django-Redis缓存

Django-Redis官方文档:https://django-redis-chs.readthedocs.io/zh_CN/latest/
Django-Redis安装包:https://pypi.org/project/django-redis/
现在我们一起来看看如果通过Django-Redis实现Django整站缓存、在开始之前我们需要先去安装Django-Redis、具体如下:

# 安装django-redis
pip install django-redis

# 在settings.py中使用django-redis
CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        # redis主机地址和链接信息
        "LOCATION": "redis://127.0.0.1:6379/1",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            # 配置Redis密码
            "PASSWORD": "123456",
            # 配置Redis创建连接的超时时间、单位秒
            "SOCKET_CONNECT_TIMEOUT": 5,
            # Redis每次读写数据的超时时间、单位秒
            "SOCKET_TIMEOUT": 5,
        }
    }
}

在启动Django-Redis缓存之前、我们先去启动项目并访问浏览器的开发者模式;我们来看看没有使用Redis缓存的页面加载时间、我们在浏览器开发者模式中的Network-Headers中可以看到Content-Length(长度): 1290;Content-Type(类型): text/html; charset=utf-8;X-Page-Duration-ms(前面我们定义的加载时间): 180(毫秒)。从下图我们可以看到、是没有页面缓存信息的。

image-20210118172155149

现在我们把缓存加上、再来看看页面的响应头有什么不一样的;这里我们配置一个整站缓存、我们需要在Middleware里面添加两个中间件、具体如下:

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

我们在CommonMiddleware的前面和后面各加一个中间件、这样加的目的是因为在系统每一个视图处理的时候、我们先从缓存系统里面去取数据;取完数据以后再做中间的处理过程、然后再更新缓存的数据、这样我们就完成了整站的缓存、我们去刷新页面看看请求的响应头信息:

image-20210118210617446

从上图我们可以看到页面请求的响应头信息:Cache-Control: max-age=600(缓存时间为600秒也就是10分钟),页面的响应时间为56ms。其实我们做缓存的目的是为了减少对数据库的访问、特别是在业务系统并发比较高的情况的下来提升系统的吞吐量;那么我们想来验证一下、如果我们重复去请求上面这个页面、它会不会往数据库里面发请求呢?我们在业务请求逻辑里面添加一个日志、如果业务请求了数据库就把日志打印出来:

image-20210118211510376

然后我们去重复刷新业务、然后看看控制台是否把上面的日志信息打印了出来:

image-20210118211631569

我们可以看到、日志并没有被打印出来;说明数据是从缓存里面获取到了;现在我们用Redis Desktop Manager管理工具、把缓存内容删掉、然后再次刷新页面看看:

image-20210118212248749

image-20210118211818626

从上图我们可以看到、当我们把缓存里面的内容删除以后;再去刷新请求页面、控制台输出了日志信息:从数据库获取数据。然后我们继续频繁刷新页面、并没有相关日志输出、代表缓存成功。

推荐文章