24.缓存

  • Post author:
  • Post category:其他


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

对于低频变动的页面可以考虑使用缓存技术,减少实际渲染次数,渲染次数少了后,用户得到的响应就会更快

有两个情况用缓存比较常见,一个是视图的渲染,你的页面比较复杂,元素比较多,加载比较慢,这个时候可以先把页面放在缓存中,这样在用户第二次访问的时候就快了。第二个是数据库的查询,你数据库中的内容很多,你可以在用户第一次使用的时候把数据库放在缓存中,这样它第二次用的时候就快了

缓存是可以设置存活时间的,因为我们的页面与数据库内容不是一成不变的,我们可以根据实际情况来设置缓存的存活时间


目录


1  配置缓存


1.1  缓存到数据库


1.1.1  配置settings.py


1.1.2  生成缓存数据表


1.2  缓存到服务器内存


1.3  缓存到服务器文件


1.4  缓存配置可以有多个


2  使用缓存


2.1  整体缓存


2.1.1  视图中使用


2.1.2  在路由中使用


2.2  局部缓存


2.2.1  引入cache对象


2.2.2  设置缓存内容 cache.set()


2.2.3  取出缓存 cache.get()


2.2.4  增加缓存 cache.add()


2.2.5  取不到就存 cache.get_or_set()


2.2.6  批量存储缓存 cache.set_many()


2.2.7  批量提取缓存 cache.get_many()


2.2.8  删除缓存 cache.delete()


2.2.9  批量删除缓存 cache.delete_many()


3  浏览器缓存


3.1  强缓存


3.1.1  前进与后退


3.1.2  整体缓存页面


3.2  协商缓存




1  配置缓存

缓存有很多种介质可以存储缓存



1.1  缓存到数据库



1.1.1  配置settings.py

将缓存的数据存在数据库中,虽然还是从数据库拿数据,但缓存数据表中的数据是不多的,所以速度要比直接从总数据表拿数据快

我们在settings.py中需要创建一个字典CACHES

字典中key的意思是

  • BACKEND 缓存引擎,数据库缓存我们就这样写就好
  • LOCATION 缓存表名称
  • TIMEOUT 缓存保存时间,单位为秒。可以不写,不屑默认是300s,如果过了300秒没存进去,这缓存我就不存了
  • OPTIONS 一些选项

    • MAX_ENTRIES 缓存表最大数据数,可以不写,不写默认为300条
    • CULL_FREQUENCY 当缓存表达到最大数据数时,删除1/x的缓存数据,我上面给的是2,那就是如果我到达了缓存最大数据数的时候,就删除表中1/2的数据



1.1.2  生成缓存数据表

使用之前我们需要在项目数据库中加入缓存数据表 输入 python manage.py createcachetable

之后我们去mysql中查看,发现my_cache_table已经创建完毕

我们看一下这个表的内容

从上至下依次是 缓存键,缓存值,过期时间



1.2  缓存到服务器内存

这个平时用用就可以了,如果是正式上线会将缓存存到缓存性的数据库redis中

  • unique-snowflake是雪花算法寻址



1.3  缓存到服务器文件

我在项目路径下创建了一个文件夹cache

1.4  缓存配置可以有多个

缓存可以有多个相同类型或不同类型的缓存,只要名字不同就行

最好是搞一个default的缓存,在引入对象的时候会用到



2  使用缓存

我们下面以缓存到数据库为例

为了测试是否走的是缓存,我们加上一个视图

再加上一个路由

访问这个路由你每一次刷新页面,都会显示访问的时间戳

2.1  整体缓存

整体缓存就是把整个页面都扔到缓存中



2.1.1  视图中使用

我们可以在视图中使用cache_page装饰器,cache_page的参数是该缓存的有效期,单位为秒

如果缓存在有效期内会直接使用缓存的数据,如果不在有效期内会重新走一遍视图获取数据

我们访问一下该路由

再刷新一下

发现时间戳相同,我们的缓存生效了

我们去mysql中查看,发现缓存表中有存储的数据

2.1.2  在路由中使用

屏蔽掉刚刚视图中的缓存装饰器

清空缓存表

在路由加入cache_page,用法与视图中使用相似,第一个参数是过期时间,第二个参数的要缓存的视图

访问一下

刷新一下

时间戳没有变化,缓存生效

数据表中增加了数据

2.2  局部缓存

整体缓存只能缓存某个整体页面,我们没法对整体页面进行操作,局部缓存可以缓存某个变量,局部缓存我们只能在视图中操作



2.2.1  引入cache对象



2.2.1.1  方式一

引入caches,然后通过caches引入settings.py中设置的不同的缓存

2.2.1.2  方法二

引入cache,cache相当于settings.py中的默认项,我们后面对cache直接使用就行了

我们后面就使用方法二引入后操作缓存



2.2.2  设置缓存内容 cache.set()

使用cache.set()的方式存储缓存,返回值无论成功与否都是None,set()有三个参数,依次是

  • key 键,需要传入字符串形式
  • value 值,任何python变量都可以
  • timeout 过期时间,可以不给,如果不给就按settings.py中的cache设置的来,单位为秒

仅仅设置而不使用的话,我们访问后依然是不同的时间戳

但存储的时候在缓存数据库中会有存储的数据

当你使用同一个key存储多次的时候,后面的值会覆盖掉前面的值

2.2.3  取出缓存 cache.get()

参数为key,存储时用的key放在这里就可以拿出来了,如果没有指定的key会返回None

有就用,没有就存,这样我们访问后再刷新,时间戳是相同的

2.2.4  增加缓存 cache.add()

只有在key不存在时cache.add()会生效,如果存储成功则返回True,如果返回失败则返回False

我们如果使用cache.add()增加缓存的话,在上面的逻辑中,你去的时候就不用进行判断了

但是会出现获取不到的情况

这个是因为在程序走到这里的时候,由于之前有该key的cache但所剩的时间极短,所以没添加进去且在后面会获取不到

2.2.5  取不到就存 cache.get_or_set()

有三个参数,依次是

  • key 缓存的键
  • value 缓存的值
  • timeout 过期时间,单位为秒

使用get_or_set()对于上面的逻辑来说不需要进行判断,而且使用get_or_set不会出现获取到None的情况

get_or_set的返回值是设置的value值

2.2.6  批量存储缓存 cache.set_many()

有两个参数,依次是

  • dict 要存储的内容,我们把要存储的内容都放到一个字典中
  • timeout 过期时间,单位为秒

set_many()存储的数据不能使用get()取,如果用get取是无效的

set_many()会将没有存储成功的数据作为列表返回,如果都成功了就会返回一个空数组

2.2.7  批量提取缓存 cache.get_many()

get_many()的参数为要提取的键列表,get_many()的返回值是一个字典,你需要用get()拿到指定键的内容

像我这样写会出现None的情况



2.2.8  删除缓存 cache.delete()

参数为缓存的key

这样写页面上返回的就永远是None



2.2.9  批量删除缓存 cache.delete_many()

参数为要删除键的数组

这样页面上会永远显示None



3  浏览器缓存

浏览器本身是自带缓存的,分为两大类,强缓存与协商缓存



3.1  强缓存

强缓存不会向服务器发送请求,直接从缓存中读取资源。



3.1.1  前进与后退

一般浏览器,点击后退再前进回来就不会向服务器发送请求

如果你第一次访问的时候,会有响应的信息

但如果访问一个别的地址后再进行后退,则没有响应信息,我们发现时间戳也没变,没有进行请求

3.1.2  整体缓存页面

我们现在使用将页面整体缓存的视图

之后我们访问一下test_cache这个路由

发现在响应头中多了两个值(使用局部缓存没有这两个值),这两个值都是控制缓存的时间的,Cache-Control是相对时间,Expires是绝对时间,两者同时存在优先使用Cache-Control



3.2  协商缓存

协商缓存的内容是静态文件,大图片这种大型文件

当这些大文件缓存到期后,与服务器进行通信,如果服务器那边有要求更改就重新获取文件,如果没有要求更改就保留原来的缓存,优点是不用每次缓存到期都拿新的

这个一般有两种方式,视频中也没说怎么实现,我们简单了解一下就行

1.Last-Modified响应头与If-Modified-Sine请求头

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

2.ETage响应头和If-None-Match请求头

  • ETage是服务器响应请求时,返回当前资源文件的一个唯一标识(由服务器生成),只要资源有变化,ETag就会重新生成
  • 缓存到期后,浏览器将ETag响应头的值作为If-None-Match请求头的值,给服务器发请求协商;服务器接到请求头后,对比文件标识,不一致则认为资源不可用,返回200响应码(响应体为最新资源);可用则返回304响应码

第一种方式是算时间,第二种方式是算哈希值,哈希值会比算时间多占用一些计算资源,如果这两种方案同时出现浏览器优先使用ETag



版权声明:本文为potato123232原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。