24.缓存

缓存(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

24.缓存_第1张图片

字典中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已经创建完毕

24.缓存_第2张图片

我们看一下这个表的内容

24.缓存_第3张图片

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

1.2  缓存到服务器内存

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

24.缓存_第4张图片

  • unique-snowflake是雪花算法寻址

1.3  缓存到服务器文件

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

24.缓存_第5张图片

1.4  缓存配置可以有多个

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

24.缓存_第6张图片

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

2  使用缓存

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

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

24.缓存_第7张图片

再加上一个路由

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

24.缓存_第8张图片

24.缓存_第9张图片

2.1  整体缓存

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

2.1.1  视图中使用

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

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

24.缓存_第10张图片

我们访问一下该路由

24.缓存_第11张图片

再刷新一下

24.缓存_第12张图片

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

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

24.缓存_第13张图片

2.1.2  在路由中使用

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

24.缓存_第14张图片

清空缓存表

24.缓存_第15张图片

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

24.缓存_第16张图片

访问一下

24.缓存_第17张图片

刷新一下

24.缓存_第18张图片

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

数据表中增加了数据

24.缓存_第19张图片

2.2  局部缓存

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

2.2.1  引入cache对象

2.2.1.1  方式一

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

24.缓存_第20张图片

24.缓存_第21张图片

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设置的来,单位为秒

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

24.缓存_第22张图片

24.缓存_第23张图片

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

24.缓存_第24张图片

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

24.缓存_第25张图片

2.2.3  取出缓存 cache.get()

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

24.缓存_第26张图片

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

24.缓存_第27张图片

24.缓存_第28张图片

2.2.4  增加缓存 cache.add()

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

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

24.缓存_第29张图片

24.缓存_第30张图片

24.缓存_第31张图片

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

24.缓存_第32张图片

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

2.2.5  取不到就存 cache.get_or_set()

有三个参数,依次是

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

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

24.缓存_第33张图片

get_or_set的返回值是设置的value值

24.缓存_第34张图片

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

有两个参数,依次是

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

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

24.缓存_第35张图片

24.缓存_第36张图片

24.缓存_第37张图片

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

24.缓存_第38张图片

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

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

24.缓存_第39张图片

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

2.2.8  删除缓存 cache.delete()

参数为缓存的key

24.缓存_第40张图片

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

24.缓存_第41张图片

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

参数为要删除键的数组

24.缓存_第42张图片

这样页面上会永远显示None

24.缓存_第43张图片

3  浏览器缓存

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

3.1  强缓存

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

3.1.1  前进与后退

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

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

24.缓存_第44张图片

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

24.缓存_第45张图片

3.1.2  整体缓存页面

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

24.缓存_第46张图片

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

24.缓存_第47张图片

发现在响应头中多了两个值(使用局部缓存没有这两个值),这两个值都是控制缓存的时间的,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

你可能感兴趣的:(Django笔记,缓存)