django的缓存机制
django设置缓存
一、设置缓存
django支持基于数据库的、文件的和内存的缓存。通常我们首先要对其进行设置。django关于缓存的设置都位于settings.py中的caches配置项中。
django支持下面几种缓存系统:
1. memcached
- memcached是django原生支持的缓存系统,速度快,效率高。memcached是一种基于内存的缓存服务,起初是为了解决livejournal.com社交网站的负载问题而开发的,后来由danga公司开源。 它被类似facebook和*这种大型网站使用,用来减少数据库访问次数,显著地提高了网站的性能。
- memcached会启动一个守护进程,并分配单独的内存块。其主要工作就是为缓存提供一个快速的添加,检索,删除的接口。所有的数据直接存储在内存中,所以它不能取代数据库或者文件系统的功能。如果你对缓存很熟悉,这些内容都很好理解。
如果你是新手,那么要清楚:
- memcached不是django自带的软件,而是一个独立的软件,需要你自己安装、配置和启动服务;
- memcached安装好了后,还要安装python操作memcached的依赖库,最常用的是python-memcached和pylibmc;
- 上面两个条件都满足了后,还要在django中进行配置。
配置方法:
-
根据你安装的python依赖库不同,将caches的backend设置为
django.core.cache.backends.memcached.memcachedcache 或者django.core.cache.backends.memcached.pylibmccache
设置location为你的memecached守护进程所在的主机ip和进程端口,格式为ip:port的字符串。或者unix:path的形式,在unix操作系统中。
-
下面是一个参考例子,memcached运行在
localhost (127.0.0.1) port 11211
,使用了python-memcached
库:caches = { 'default': { 'backend': 'django.core.cache.backends.memcached.memcachedcache', 'location': '127.0.0.1:11211', } }
-
下面的memcached运行在本地的unix socket上:
/tmp/memcached.sock
,依赖python-memcached
:caches = { 'default': { 'backend': 'django.core.cache.backends.memcached.memcachedcache', 'location': 'unix:/tmp/memcached.sock', } }
-
下面的memcached运行在
/tmp/memcached.sock
,不带unix:/
前缀,依赖pylibmc库:caches = { 'default': { 'backend': 'django.core.cache.backends.memcached.pylibmccache', 'location': '/tmp/memcached.sock', } }
-
memcached支持分布式服务,可能同时在几台机器上运行,将它们的ip地址都加入到location中,如下所示:
caches = { 'default': { 'backend': 'django.core.cache.backends.memcached.memcachedcache', 'location': [ '172.19.26.240:11211', '172.19.26.242:21423', '172.19.26.244:11213', ] } }
基于内存的缓存系统有个明显的缺点就是断电数据丢失,尤其是memcached这种不支持序列化的缓存,所以请大家务必要注意数据的安全性。
其实对于当下,redis作为缓存更好,还支持序列化。
2. 数据库缓存
-
我们使用缓存的很大原因就是要减少数据库的操作,如果将缓存又存到数据库,做了无用功。所以,尽量不要使用基于数据库的缓存,这里也不做具体介绍,给个简单的配置范例吧:
caches = { 'default': { 'backend': 'django.core.cache.backends.db.databasecache', 'location': 'my_cache_table', # 数据库表名字 } } # 注:执行创建专门用于存储缓存数据表命令 python manage.py createcachetable
但是在某些情况下,还是有一些用途的,比如你有一个高速、高效索引的数据库。
redis缓存
准备软件:django-redis第三方模块
开始使用:
安装:pip install django-redis
-
配置:
caches = { "default": { "backend": "django_redis.cache.rediscache", "location": "redis://127.0.0.1:6379/1", "options": { "client_class": "django_redis.client.defaultclient", } } }
-
作为
session backend
使用配置session_engine = "django.contrib.sessions.backends.cache" session_cache_alias = "default"
3. 文件系统缓存
连数据库我们都觉得慢,那么基于文件系统的呢?更慢!不过在你手里没有redis、memcached和数据库的时候,也可以勉为其难的用一下。下面给出两个配置案例:
-
基于unix系统:
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', } }
4. 基于本地内存的缓存
-
如果你的本地主机内存够大够快,也可以直接使用它作为缓存。配置如下:
caches = { 'default': { 'backend': 'django.core.cache.backends.locmem.locmemcache', 'location': 'unique-snowflake', # 缓存超时时间(默认300,none表示永不过期,0表示立即过期) 'timeout': 300, 'options':{ # 最大缓存个数(默认300) 'max_entries': 300, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/cull_frequency(默认3) 'cull_frequency': 3, }, } } # 缓存视图 from django.views.decorators.cache import cache_page@cache_page(5) # 参数超时时间,5秒后过期 def student_list(request, *args, **kwargs): students = models.student.objects.all() print('students') return render(request, 'student_list.html', {'students': students})
5. 开发调试用的缓存
django很贴心的为我们设计了一个开发用的缓存。当你的生产环境是个大型的缓存系统,而你在开发的时候又没有相应的缓存系统支持,或者不想用那种笨重的大家伙进行开发。但实际开发过程中,你又不得不接入缓存系统,使用缓存的api,这种情况下,开发用的缓存就很顺手了。
-
配置如下:
caches = { 'default': { 'backend': 'django.core.cache.backends.dummy.dummycache', 'timeout': 300, # 缓存超时时间(默认300,none表示永不过期,0表示立即过期) 'options':{ # 最大缓存个数(默认300) 'max_entries': 300, # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/cull_frequency(默认3) 'cull_frequency': 3, }, 'key_prefix': '', # 缓存key的前缀(默认空) 'version': 1, # 缓存key的版本(默认1) 'key_function': 函数名 # 生成key的函数(默认函数会生成为:【前缀:版本:key】) } }
6. 自定义缓存后端
-
最高境界当然是使用自己开发的缓存系统了,django是支持的,但前提是你要有那能力!配置很简单:
caches = { 'default': { 'backend': 'path.to.backend', } }
7. 缓存参数
- 上述每一个缓存后端都可以设置一些额外的参数来控制缓存行为,可以设置的参数如下:
-
timeout
:缓存的默认过期时间,以秒为单位,默认是300秒none表示永远不会过期。设置成0将造成缓存立即失效(缓存就没有意义了)。 -
options
:可选参数,根据缓存后端的不同而不同。 -
key_prefix
:django服务器使用的所有缓存键的字符串。 -
version
:由django服务器生成的默认版本号。 -
key_function
:一个字符串,其中包含一个函数的点路径,该函数定义了如何将前缀,版本和密钥组合成最终缓存密钥。
-
-
下面例子中配置了一个基于文件系统的缓存后端,缓存过期时间被设置为60秒,最大条目为1000.
caches = { 'default': { 'backend': 'django.core.cache.backends.filebased.filebasedcache', 'location': '/var/tmp/django_cache', 'timeout': 60, 'options': { 'max_entries': 1000 } } }
-
以下示例配置了一个基于python-memcached库的后端,其对象大小限制为2mb:
caches = { 'default': { 'backend': 'django.core.cache.backends.memcached.memcachedcache', 'location': '127.0.0.1:11211', 'options': { 'server_max_value_length': 1024 * 1024 * 2, } } }
-
以下是基于pylibmc库的后端配置,该后端启用二进制协议、sasl认证和ketama行为模式:
caches = { 'default': { 'backend': 'django.core.cache.backends.memcached.pylibmccache', 'location': '127.0.0.1:11211', 'options': { 'binary': true, 'username': 'user', 'password': 'pass', 'behaviors': { 'ketama': true, } } } }
二、全站应用缓存
缓存系统最简单的使用方法是缓存整个网站。
-
这需要额外将'django.middleware.cache.updatecachemiddleware'和'django.middleware.cache.fetchfromcachemiddleware'添加到middleware设置中,如下所示:
middleware = [ 'django.middleware.cache.updatecachemiddleware', # 必须放在最上面 # 其他中间件... 'django.middleware.cache.fetchfromcachemiddleware', # 必须放在最后]
注意:
update
中间件必须放在列表的开始位置,而fectch
中间件,必须放在最后。 这是django使用中间件的规则,它们是有顺序关系的,从上到下依次执行。请求到来先执行中间件process_request方法,这个时候要先看缓存中有没有数据,在fectch中间件,中有一个process_request方法,用于获取缓存数据,如果有就不进行路由匹配了,直接将数据返回,所以要放在最后。当数据将要返回给浏览器的时候,更新一下缓存,将数据放到缓存中,所以在update中间件中有一个process_response方法,用来更新缓存数据的,所以放在最上面。-
然后,添加下面这些需要的参数到settings文件里:
cache_middleware_alias : 用于存储的缓存的别名 cache_middleware_seconds : 每个page需要被缓存多少秒. cache_middleware_key_prefix : 密钥前缀
三、视图应用缓存
-
另一个使用缓存框架的方法是对视图的输出进行缓存。在django.views.decorators.cache定义了一个自动缓存视图响应结果的装饰器
cache_page
,使用非常简单:from django.views.decorators.cache import cache_page @cache_page(60 * 15) def my_view(request): ...
cache_page
接受一个参数:timeout,秒为单位。在上例中,my_view()
视图的结果将被缓存15分钟(为了提高可读性写成了60 * 15) -
和站点缓存一样,视图缓存与url无关。如果多个url指向同一视图,每个url将会分别缓存。 继续my_view的例子,如果urlconf如下所示:
urlpatterns = [ url(r'^foo/([0-9]{1,2})/$', my_view), ]
那么发送到
/foo/23/
和/foo/1/
的请求会被分别缓存。但是一旦一个明确的url(例如/foo/23/
) 已经被请求过了, 之后再度发出的指向该url的请求将使用缓存的内容。 -
cache_page
也可以使用一些额外的参数,比如cache,这个参数指示具体使用的缓存后端。@cache_page(60 * 15, cache="special_cache") def my_view(request): ...
-
还可以采用可选的关键字参数
key_prefix
在每个视图中指定具体的缓存前缀,如下所示:@cache_page(60 * 15, key_prefix="site1") def my_view(request): ...
四、缓存模板片段
我们还可以使用
cache
模板标签来缓存模板的一个片段。要使用这个标签,首先要在模版的顶部位置添加{% load cache %}
。-
模板标签
{% cache %}
将在设定的时间内,缓存标签块中包含的内容。它最少需要两个参数:缓存时间(以秒为单位)以及给缓存片段起的名称。像这样:{% load cache %} {% cache 500 sidebar %} .. sidebar .. {% endcache %}
-
还可以依据片段内的动态内容缓存多个版本。如上个例子中,可以给站点的每个用户生成不同版本的sidebar缓存。 只需要给
{% cache %}
标签再传递一个参数来标识区分这个缓存片段,如下所示:{% load cache %} {% cache 500 sidebar request.user.username %} .. sidebar for logged in user .. {% endcache %}
-
缓存超时参数可以是个模板变量,只要模板变量可以解析为整数值即可。例如,如果模板变量my_timeout设置为值600,则以下两个示例是等效的:
{% cache 600 sidebar %} ... {% endcache %} {% cache my_timeout sidebar %} ... {% endcache %}
注:来源https://blog.csdn.net/weixin_39726347/article/details/88035356
上一篇: 算法复杂度O(logn)详解
推荐阅读
-
[原创]分布式系统之缓存的微观应用经验谈(一) 【设计细节篇】
-
[原创]分布式系统之缓存的微观应用经验谈(二) 【主从和主备高可用篇】
-
Django+vue跨域问题解决的详细步骤
-
利用一个简单的例子窥探CPython内核的运行机制
-
linux 可执行文件与写操作的同步问题(文件读写操作产生的锁机制)
-
Django的model中日期字段设置默认值的问题
-
django(1045,"Accessdeniedforuser'wccLab'@'localhost'(usingpassword:no)BUG问题的解决教程
-
Django之Mode的外键自关联和引用未定义的Model方法
-
Python的Django框架使用入门指引
-
聊一聊CPU缓存的作用 是越大越好么?