17. Django进阶:缓存

一、定义

缓存是一类可以更快的读取数据的介质统称,也指其他可以加快数据读取的存储方式。一般用来存储临时数据,常用的介质是读取速度很快的内存

二、意义

视图渲染有一定成本,数据库的频繁查询过高。所以对于低频变动的页面可以考虑使用缓存技术,减少实际渲染次数,用户拿到响应的时间成本会更低

三、案例分析

from django.shortcuts import render

def index(request):
	# 时间复杂度极高的渲染
	book_list = Book.objects.all() # → 假设此处耗时2S
	return render(request, 'index.html', locals())

四、优化思想(官网)

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
获取一个请求URL,在缓存中寻找对应界面
如果缓存中有界面:
	直接返回缓存界面
不然:
	生成界面
	界面放到缓存中
	返回生成的界面

五、缓存场景

  1. 博客列表页
  2. 电影商品详情页

场景特点:缓存的地方,数据变动频率较少

六、缓存配置

6.1. 数据库缓存

将缓存的数据存储在数据库中

说明:尽管存储介质没有更换,但是当把一次负责查询的结果直接存储到表中,比如多个条件的过滤查询结果,可避免重复进行复杂查询,提升效率。

配置样例:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': 'my_cache_table',
        'TIMEOUT': 300,  # 缓存保存时间 单位秒 默认值300
        'OPTIONS': {
            'MAX_ENTRIES': 300,  # 缓存最大数据条数
            'CULL_FREQUENCY': 2,  # 缓存条数达到最大时删除1/x的缓存数据
        }
    }
}

6.2. 本地内存缓存

数据缓存到服务器内存中

配置样例:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.locMemCache',
        'LOCATION': 'unique-snowflake'
    }
}

6.4. 文件系统缓存

将缓存的数据存储到本地文件中

配置样例:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': '/var/tmp/django_cache',  # 这个是文件夹的路径
        # 'LOCATION': 'c:\test\cache',  # windows下示例
    }
}

七、数据库缓存

在这里插入图片描述

数据库缓存配置,需要手动执行创建表的命令。

命令:

$ python3 manage.py createcachetable

在这里插入图片描述

在这里插入图片描述

八、整体缓存策略

缓存整个界面

8.1. 视图函数

视图函数中进行缓存,使用装饰器,样例

from django.views.decorators.cache import cache_page

@cache_page(30) → 单位s
def my_view(request)
	···

8.2. 路由

路由中进行缓存,样例

from django.views.decorators.cache import cache_page

urlpatterns = [
	path('for/', cache_page(60)(my_view)),
]

8.3. 实现缓存

以视图函数缓存为例:

在这里插入图片描述

访问http://127.0.0.1:8000/

  • 首次访问会生成时间戳,缓存15S
  • 15S内再次访问,时间戳相同
  • 15S后再次访问,时间戳更新

即:有缓存走缓存,没缓存,生成新数据

九、局部缓存策略

案例分析

from django.shortcuts import render

def index(request):
	# 时间复杂度极高的渲染
	book_list = Book.objects.all() # → 假设此处耗时2S
	return render(request, 'index.html', locals())

局部缓存更加灵活,想缓存什么就缓存什么

9.1. 缓存API的使用

先引入cache对象

方式一:使用caches['CACHE配置KEY']导入具体对象

from django.core.cache import caches
cache = cache['default']
cache1 = cache['myalias']
cache2 = cache['myalias_2']

方式二:from django.core.cache import cache相当于直接引入CACHES配置项中的default

9.2. 缓存API

9.2.1. set

cache.set(key, value, timeout):存储缓存

  • key:缓存的key,字符串类型
  • value:Python对象
  • timeout:缓存存储时间(s),默认为CACHES中的TIMEOUT值

返回值:None

9.2.2. get

cache.get(key):获取缓存

  • key:缓存的key

返回值:为key的具体值,如果没有数据,则返回None

测试:在这里插入图片描述

9.2.3. add

cache.add(key, value):存储缓存,只在key不存在时生效

返回值:True【存储成功】 Or False【存储失败】

9.2.4. get_or_set

cache.get_or_set(key, value, timeout):如果未获取到数据,则执行set操作

返回值:value

9.2.5. set_many

cache.set_many(dict, timeout):批量存储操作

  • dict:key和value的字典
  • timeout:存储时间(s)

返回值:插入不成功的key的数组

9.2.6. get_many

cache.get_many(key_list):批量获取缓存数据

  • key_list:包含key的数组

返回值:取到的key的value的字典

9.2.7. delete

cache.delete(key):删除key的缓存数据

返回值:None

9.2.8. delete_many

cache.delete_many(key_list):批量删除

返回值:None

十、浏览器缓存策略

10.1. 定义

浏览器也具备缓存技术,对于浏览器来说,每次向服务器发出请求都是耗时操作,如果本身浏览器内部就具备当前URL的内容,则一定时间内可以不必给服务器发消息,从而提升网民体验,降低服务器请求压力

在这里插入图片描述

10.2. 强缓存

不会向服务器发送请求,直接从缓存中读取数据

10.2.1. Expires

响应头:Expires

  • 定义:缓存过期时间,用来指定资源到期的时间,是服务器端的具体的时间点
  • 样例:Expires:Thu,02 Apr 2030 05:14:08 GMT

绝对时间

10.2.2. Cache-Control

在HTTP/1.1中,Cache-Control主要用于控制网页缓存

比如当Cache-Control:max-age=120,代表请求创建时间后的120秒,缓存失效

说明:目前服务器都会带着这两个头同时响应给浏览器,浏览器优先使用Cache-Control

相对时间

10.3. 协商缓存

强缓存中的数据一旦过期,还需要跟服务器进行通信,从而获取最新数据。避免重复获取数据

思考:如果强缓存的数据是一些静态文件,大图片等

解答:考虑到大图片这类比较费带宽且不宜变化的数据,强缓存时间到期后,浏览器回去跟服务器协商,当前缓存是否可用,如果可用,服务器不必返回数据,浏览器继续使用原来的缓存,如果文件不可用,则返回最新数据

10.3.1. Last-Modified & If-Modified-Since

响应头:Last-Modified

请求头:If-Modified-Since

说明:

  1. Last-Modified为文件的最近修改时间,浏览器第一次请求静态文件时,服务器如果返回Last-Modified响应头,则代表该资源为需要协商的缓存
  2. 当缓存到期后,浏览器将获取到的Last-Modified值作为请求头If-Modified-Since的值,与服务器发请求协商
    • 服务端返回304响应码,代表缓存继续使用,【响应体为空】
    • 服务端返回200响应码,代表缓存不可用,【响应体为最新资源】

10.3.2. ETag & If-None-Match

说明

  1. Etag是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成),只要资源有变化,Etag就会重新生成
  2. 缓存到期后,浏览器将ETag响应头的值作为If-None-Match请求头的值,给服务器发请求协商,服务器接收到请求头后,对比文件标识
    • 不一致则认为资源不可用,返回200响应码,【响应体为最新资源】
    • 一致则认为资源可用,返回304响应码,【响应体为空】
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

KaiSarH

如果觉得文章不错,可以支持下~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值