Django的缓存

Django给我们提供了三种缓存方式:

  • 站点级缓存————缓存整个网站
  • 单个view缓存————对单个有效的视图的输出进行缓存
  • 模板片段缓存————缓存模板里面的某一部分内容

为什么要用缓存

由于Django是动态网站,所以每次请求均会去数据库进行相应的操作,当程序访问量大时,耗时必然会增加,最简单解决方式是使用缓存,将某个views的返回值保存至内存或者memcache中,5分钟内再有人来访问时(时间可以设置),则不再去执行view中的操作,而是直接从缓存中读取内容并直接返回。
另外,缓存只是一类统称,一般其介质是速度很快的内存,但也可以是能加快数据读取的其它方式。

什么时候适合用缓存

对页面实时性要求不高的页面,可以用缓存。

缓存的配置

django配置缓存提供了6种方式(settings.py)。

  • 开发调试
  • 内存
  • 文件
  • 数据库
  • Memcache缓存(python-memcached模块)
  • Memcache缓存(pylibmc模块)

开发调试

说明:此为开始调试用,实际内部不做任何操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache', # 引擎
'TIMEOUT': 300, # 缓存超时时间(默认300秒,None表示永不过期,0表示立即过期)
'OPTIONS':{
'MAX_ENTRIES': 300, # 最大缓存个数(默认300)
'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3),3:表示1/3
},

# 这边只的是缓存的key:p1:1:func_name
'KEY_PREFIX': 'p1', # 缓存key的前缀(默认空)
'VERSION': 1, # 缓存key的版本(默认1)
'KEY_FUNCTION':"path.to.key_func" # 生成key的函数(默认函数会生成为:【前缀:版本:key】)
}
}

其他除了引擎不一样,其他的都是通用的,这边只的是缓存的key:p1:1:func_name的源码如下:所以我们就可以自定义这个key的格式。
# 自定义key
def default_key_func(key, key_prefix, version):
"""
Default function to generate keys.

Constructs the key used by all other methods. By default it prepends
the `key_prefix'. KEY_FUNCTION can be used to specify an alternate
function with custom key making behavior.
"""
return '%s:%s:%s' % (key_prefix, version, key)

def get_key_func(key_func):
"""
Function to decide which key function to use.

Defaults to ``default_key_func``.
"""
if key_func is not None:
if callable(key_func):
return key_func
else:
return import_string(key_func)
return default_key_func

内存

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', # 引擎
'LOCATION': 'unique-snowflake', # 被用于标识各个内存存储位置。
'TIMEOUT': 300, # 缓存超时时间(默认300秒,None表示永不过期,0表示立即过期)
'OPTIONS':{
'MAX_ENTRIES': 300, # 最大缓存个数(默认300)
'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3),3:表示1/3
},

# 这边只的是缓存的key:p1:1:func_name
'KEY_PREFIX': 'p1', # 缓存key的前缀(默认空)
'VERSION': 1, # 缓存key的版本(默认1)
'KEY_FUNCTION':"path.to.key_func" # 生成key的函数(默认函数会生成为:【前缀:版本:key】)
}
}

注意,每个进程将有它们自己的私有缓存实例,这意味着不存在跨进程的缓存。这也意味着本地内存缓存不是特别节省内存,因此它不适合生产环境,不过它在开发环境中表现很好。

文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', # 引擎
'LOCATION': '/var/tmp/django_cache', # 缓存存放的路径
'TIMEOUT': 300, # 缓存超时时间(默认300秒,None表示永不过期,0表示立即过期)
'OPTIONS':{
'MAX_ENTRIES': 300, # 最大缓存个数(默认300)
'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3),3:表示1/3
},

# 这边只的是缓存的key:p1:1:func_name
'KEY_PREFIX': 'p1', # 缓存key的前缀(默认空)
'VERSION': 1, # 缓存key的版本(默认1)
'KEY_FUNCTION':"path.to.key_func" # 生成key的函数(默认函数会生成为:【前缀:版本:key】)
}
}

数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache', # 引擎
'LOCATION': 'my_cache_table', # 设置一个数据库存放缓存的表名
'TIMEOUT': 300, # 缓存超时时间(默认300秒,None表示永不过期,0表示立即过期)
'OPTIONS':{
'MAX_ENTRIES': 300, # 最大缓存个数(默认300)
'CULL_FREQUENCY': 3, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3),3:表示1/3
},

# 这边只的是缓存的key:p1:1:func_name
'KEY_PREFIX': 'p1', # 缓存key的前缀(默认空)
'VERSION': 1, # 缓存key的版本(默认1)
'KEY_FUNCTION':"path.to.key_func" # 生成key的函数(默认函数会生成为:【前缀:版本:key】)
}
}

注:执行创建表命令 python manage.py createcachetable

Memcache缓存(python-memcached模块)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#单台机器
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
#其他的配置和开发调试版本一样
}

#存放本地的
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': 'unix:/tmp/memcached.sock',
}
#其他的配置和开发调试版本一样
}

#支持集群,负载均衡
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',

#设置权重
#('172.19.26.240:11211',10),
#('172.19.26.242:11211',20),
]
}
# 其他的配置和开发调试版本一样
}

Memcache缓存(pylibmc模块)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '127.0.0.1:11211',
}
}

CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '/tmp/memcached.sock',
}
}

CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}

django中缓存设置参数

1
2
3
4
5
6
7
8
9
BACKEND    # 引擎
LOCATION # 被用于标识各个内存存储位置。如果只有一个 locmem 缓存,你可以忽略 LOCATION 。但是如果你有多个本地内存缓存,那么你至少要为其中一个起个名字,以便将它们区分开。
TIMEOUT # 缓存的默认过期时间,以秒为单位,默认是300秒,None表示永远不会过期,设置成0则缓存立即失效
OPTIONS # 可选参数,根据缓存后端的不同而不同。
MAX_ENTRIES # 缓存中存放的最大条目数
CULL_REQUENCY # 当达到 max_entries 的时候,被淘汰的部分条目。实际的比率是1/cull_frequency,把 cull_frequency 的值设置为 0 意味着当达到 max_entries 时,缓存将被清空。这将以很多缓存丢失为代价,大大提高接受访问的速度。这个值默认是3
KEY_PREFIX # Django服务器使用的所有缓存键的字符串,默认空。
VERSION # 由Django服务器生成的默认版本号, 默认1。
KEY_FUNCTION # 一个字符串,其中包含一个函数的点路径,该函数定义了如何将前缀,版本和密钥组合成最终缓存密钥。

django 缓存应用

站点级缓存

django.middleware.cache.UpdateCacheMiddlewaredjango.middleware.cache.FetchFromCacheMiddleware添加到MIDDLEWARE设置中

1
2
3
4
5
6
7
8
9
10
11
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
]

注意: update中间件必须放在列表的开始位置,而fectch中间件,必须放在最后。然后,添加下面这些需要的参数到settings文件里:

1
2
3
CACHE_MIDDLEWARE_ALIAS : 用于存储的缓存的别名
CACHE_MIDDLEWARE_SECONDS : 每个page需要被缓存多少秒.
CACHE_MIDDLEWARE_KEY_PREFIX : 密钥前缀

单个view缓存

  • 在视图View中使用cache
1
2
3
4
5
6
7
8
9
from django.http import HttpResponse
from django.views.decorators.cache import cache_page

@cache_page(60 * 15)
def my_view(request):
do_something()
return HttpResponse('response body', status=200)

cache_page接受一个参数:timeout,秒为单位。
  • 在路由URLConf中使用cache
1
2
3
4
from django.views.decorators.cache import cache_page

urlpatterns = [
path('foo/<int:code>/', cache_page(60 * 15)(my_view)),

模板片段缓存

1
2
3
4
{% load cache %}
{% cache 500 sidebar request.user.username %}
.. sidebar for logged in user ..
{% endcache %}

参考

Django缓存Cache详解

-------------本文结束感谢您的阅读-------------