- 一、Django 缓存框架
- 二、设置缓存
- 2.1 Memcached
- 2.1.1 准备工作
- 2.1.2 设置Memcached
- 2.1.3 使用多个Memcached服务器
- 2.1.4 Memcached的缺点
- 2.2 数据库缓存
- 创建缓存表
- 2.3 文件系统缓存
- 2.4 本地内存缓存
- 2.5 虚拟缓存(用于开发模式)
- 2.6 自定义缓存后端
- 2.7 缓存参数
- 三、缓存站点
- 四、缓存视图
- 在路由中指定视图缓存
- 五、缓存模板片段
动态网站在收到每一个用户请求时,都会执行查询数据库、渲染模板等操作,这些操作比单纯地从文件系统中读取文件所花费的代价昂贵的多,且不一定是必须的。
因此,我们可以将计算结果保存下来,下次直接返回保存的文件。这中节约资源的方法就是缓存。
django自带了缓存系统,提供了不同级别的缓存粒度:可以缓存特定视图的输出、计算量比较大的部分、甚至是缓存整个网站。
二、设置缓存我们需要进行设置,告诉django缓存数据应该放在哪里。这关系到缓存的性能。
2.1 MemcachedMemcached是一个完全基于内存的缓存服务器,是 Django 原生支持的最快、最高效的缓存类型。Facebook 和 Wikipedia 等网站使用它来减少数据库访问并显著提高网站性能。
Memcached以一个守护进程的形式运行,并且被分配了指定数量的 RAM。它所做的就是提供一个快速接口用于在缓存中添加,检索和删除数据。所有数据都直接存储在内存中,因此不会产生数据库或文件系统使用的开销。
2.1.1 准备工作Memcached需要我们自己安装,安装方法很简单,按照官方文档来就可以。
之后,还要安装python的memcached客户端,Django支持的两个客户端是pylibmc和pymemcache(django 3.2版本新增)。
2.1.2 设置Memcached根据安装的客户端,设置BACKEND为:
- django.core.cache.backends.memcached.PyMemcacheCache
- django.core.cache.backends.memcached.PyLibMCCache
将LOCATION设置为下面的其中一个:
-
ip:port 值:
ip 是 Memcached 守护进程的 IP 地址,port 是 Memcached 运行的端口,
-
unix:path 值:
path 是 Memcached Unix socket 文件的路径。
举例来说:
-
Memcached 运行在“127.0.0.1:11211”,使用pymemcache 客户端:
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache', 'LOCATION': '127.0.0.1:11211', } } -
Memcached 通过本地 Unix 套接字文件 /tmp/memcached.sock 使用pymemcache` 客户端:
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache', 'LOCATION': 'unix:/tmp/memcached.sock', } }
Memcached可以在多台服务器上共享一个缓存,这意味着我们可以在多台机器上运行 Memcached 守护进程,而程序将会把这组机器当作一个单一的缓存,不需要在每台机器上重复缓存值。
要使用这个特性,只需在LOCATION中设置多个地址即可:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}
2.1.4 Memcached的缺点
因为Memcached缓存的数据存储在内存中,如果服务器崩溃,数据将丢失。所以不要依赖基于内存的缓存作为你唯一的数据存储或者存储。
2.2 数据库缓存Django 可以在数据库中存储缓存数据。如果你有一个快速、索引正常的数据库服务器,这种缓存效果最好。
设置方法如下:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_cache_table', # 缓存表的名称
}
}
创建缓存表
使用数据库缓存之前,必须通过下面的命令创建缓存表:
python manage.py createcachetable
django将在数据库中创建一个表,表的表名取自LOCATION 。
如果正在使用多个数据库缓存, createcachetable 会为每个缓存创建一个表。
2.3 文件系统缓存基于文件的缓存系统会序列化缓存数据,并将每个缓存数据保存为单独的文件。显然这种缓存十分的慢,但如果没有更好的选择,也可以勉强用一下。
设置如下:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FilebasedCache',
'LOCATION': '/var/tmp/django_cache', # 缓存文件的保存路径
}
}
如果使用 Windows 系统,将驱动器号放在路径开头,如下:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FilebasedCache',
'LOCATION': 'c:/foo/bar',
}
}
目录路径应该是绝对路径——因此,它应该以文件系统根目录开始。无需担心是否需要以斜杠结尾。
2.4 本地内存缓存如果你的本地主机内存够大够快,也可以直接使用它作为缓存,并且这也是Django默认使用的缓存后端。设置如下:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
}
}
LOCATION 被用于标识各个内存存储。如果只有一个 locmem 缓存,你可以忽略 LOCATION。但是如果有多个本地内存缓存,那么至少要为其中一个起个名字,以便将它们区分开。
2.5 虚拟缓存(用于开发模式)虚拟缓存只是实现了缓存接口,并不会做其他操作。如果我们需要用到缓存,但在开发过程中不想用或没法用到对应的缓存系统支持,那么就可以使用虚拟缓存。设置如下:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
}
}
2.6 自定义缓存后端
如果上面的缓存后端都不能满足我们的要求,那我们还可以自定义缓存后端。设置时只需要将后端设置为自定义的后端即可:
CACHES = {
'default': {
'BACKEND': 'path.to.backend',
}
}
而关于缓存后端的自定义方法,建议参照官方文档中的API:传送门
2.7 缓存参数缓存参数用来控制缓存的行为,它们依旧是设置在CACHES中。参数详情如下:
-
TIMEOUT:
缓存的默认过期时间,以秒为单位,默认是300秒。
设置成None表示永远不会过期;设置成0表示立即失效(没意义了)。
-
OPTIONS:
-
MAX_ENTRIES :删除旧值之前允许缓存的最大条目。默认是 300 。
-
CULL_FREQUENCY :当达到 MAX_ENTRIES 时被淘汰的部分条目,实际比率为 1 / CULL_FREQUENCY 。
设置为2时,当达到 MAX_ENTRIES 就会淘汰一半的条目(即 1 / 2 1/2 1/2)。这个参数应该是一个整数,默认为3。
设置为 0 时,意味着当达到 MAX_ENTRIES ,整个缓存都会被清空。
-
-
KEY_PREFIX:
所有缓存键的前缀,是一个字符串。
-
VERSION:
Django 服务器生成的缓存键的默认版本号。
-
KEY_FUNCTION:
一个字符串,包含一个函数的点分隔路径,该函数定义了如何将前缀、版本和键组成一个最终的缓存键。
下面是一个基于 pymemcache 的后端配置实例,它启用了客户端池(通过保持客户端连接来提高性能),将 memcache/网络错误视为缓存失效,并在连接的 socket 上设置了 TCP_NODELAY 标志:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
'LOCATION': '127.0.0.1:11211',
'OPTIONS': {
'no_delay': True,
'ignore_exc': True,
'max_pool_size': 4,
'use_pooling': True,
}
}
}
三、缓存站点
设置完毕后,使用缓存最简单的方式就是缓存整个网站。这需要在中间件(MIDDLEWARE)中添加下面两项:
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
……
'django.middleware.cache.FetchFromCacheMiddleware',
]
注意:“update” 中间件必须在列表的第一位,而“fetch”中间件必须在最后!
然后,在项目配置文件中添加下面的内容:
CACHE_MIDDLEWARE_ALIAS : 用于存储的缓存的别名 CACHE_MIDDLEWARE_SEConDS : 每个page需要被缓存多少秒 CACHE_MIDDLEWARE_KEY_PREFIX : key的前缀,当有多个站点使用同一个配置的时候,这个可以设置可以避免发生冲突四、缓存视图
缓存框架最常用的方法是缓存视图的结果。django.views.decorators.cache 定义了一个 cache_page 装饰器,它将自动缓存视图的响应:
rom django.views.decorators.cache import cache_page
@cache_page(60 * 15) # 缓存有效期,单位为秒
def my_view(request):
...
和缓存站点一样,视图缓存也是以 URL 为键。假如路由配置是这样的:
urlpatterns = [
path('foo//', my_view),
]
那么那么 /foo/1/ 和 /foo/23/ 的请求将被分别缓存。
在路由中指定视图缓存上面的方法将视图和缓存框架强行绑定在了一起,增加了系统的耦合度。django提供了另外一种缓存方法,让缓存框架与url绑定,从而使视图解脱出来,让其他想用该视图而不想用缓存的站点也可以安心使用该视图。
在 URLconf 中使用 cache_page :
urlpatterns = [
path('foo//', my_view),
]
将 my_view 包含在 cache_page 中:
from django.views.decorators.cache import cache_page
urlpatterns = [
path('foo//', cache_page(60 * 15)(my_view)),
]
五、缓存模板片段
django在模板语法中,也提供了对缓存的支持。使用cache 模板标签(tag)可以缓存页面中的一部分:
{% load cache %} 这一句要放在最顶部
{% cache 500 sidebar %}
.. sidebar ..
{% endcache %}
其中,500是缓存有效期(单位是秒),“sidebar”是对片段起的名字,必须是全局唯一的。



