Django Cache 缓存系统
缓存是指保存一些计算开销较大的数据,可以是某个网页,也可以是网页的一部分,或者仅仅只是格式化的数据,比如json等。合理运用缓存技术可以减少数据库访问次数以及计算时间,从而加快网页的访问速度。
Django提供了一个健壮的缓存系统,可以保存动态页面,这样就不必每个请求都计算一遍相同的结果。并且Django还提供了不同级别的缓存粒度:可以缓存特定视图的输出,或者只缓存那些难以生成的片段,或者缓存整个站点。
Django还能很好地处理“下游”缓存,比如基于浏览器的缓存。这些是不能直接控制的缓存类型,但是可以通过HTTP头信息给与提示,关于应该缓存站点的哪些部分,以及如何缓存。
要使用缓存系统需要先在settings.py中设置,Django提供多种缓存类型:Memcached缓存,数据库缓存,文件系统缓存,局部内存缓存和自定义缓存等。
Memcached
Memcached是Django支持的最快、最高效的缓存类型,它是一种完全基于内存的缓存服务器。它被Facebook和维基百科等网站使用,以减少数据库的访问并显著提高网站的性能。
Memcached作为一个守护进程运行,并分配了一定数量的RAM。它提供一个快速的接口用于在缓存中添加、检索和删除数据。所有数据都直接存储在内存中,因此比数据库或文件系统存储等基于硬盘的缓存方式更快。
使用该缓存类型要先安装Memcached程序,并安装Python与Memcached之间的接口库,如python-memcached和pylibmc等。安装完以后启动Memcached,在django中设置连接。
下例中的 Memcached 服务运行的主机为 127.0.0.1(本机) 、端口为 11211,用python-memcached连接:
# 此缓存使用python-memcached模块连接memcache 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', ] # 我们也可以给缓存机器加权重,权重高的承担更多的请求,如下 'LOCATION': [ ('172.19.26.240:11211',5), ('172.19.26.242:11211',1), ] } }
安装(Linux)
sudo apt install memcached
启动
service memcached start #方式一 /usr/bin/memcached -u memcache -m 1024 -p 11222 -l 0.0.0.0 -d start # 方式二
- -d:这个参数是让memcached在后台运行
- -m:指定占用多少内存。以M为单位,默认为64M。
- -p:指定占用的端口。默认端口是11211。
- -l:别的机器可以通过哪个ip地址连接到我这台服务器,如果想要让别的机器连接,就必须设置-l 0.0.0.0
检测启动成功
ps aux|grep memcached # memcache 11025 0.0 0.1 326560 2372 ? Ssl Aug28 0:01 memcached -u memcache -m 512 -p 11211 -l 0.0.0.0 -d
注意:添加的键的命名方式如下
def default_key_func(key, key_prefix, version): return '%s:%s:%s' % (key_prefix, version, key)
如要修改,可在setting.py文件中添加配置'KEY_FUNCTION'
CACHES = { 'default': { 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', 'LOCATION': '172.19.26.240:11211', 'KEY_FUNCTION': lambda: key_prefix,version,key : 'Django'+key, } }
文件系统缓存
基于文件的后端将每个缓存值序列化并存储于一个单独的文件中,无需安装其他的程序,设置好就能用,方法如下:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
}
}
保存缓存文件的文件夹路径应该是绝对的——也就是说,它应该从文件系统的根目录开始,路径是否以斜杠结尾并不重要。确保该目录已经存在,并且运行Web服务器的用户具有可读和可写该文件夹的权限。
数据库缓存
使用数据库作为缓存,会将缓存的数据保存在指定的表中,LOCATION为表名:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_cache_table',
}
}
然后在数据库中创建该表:
python manage.py createcachetable
局部内存缓存
这种缓存方式会将缓存保存于每个进程的内存中,这意味着缓存不可跨进程共享。很显然这样比较浪费内存空间,故而不适合用于生产环境,但对于开发环境则比较方便。
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
}
}
缓存参数
除了指定缓存的方式外,还可以指定一些参数。如下:
TIMEOUT:过期时间,单位为秒
MAX_ENTRIES:最大缓存数,当缓存的数量超过后删除旧的缓存
其他参数请参考Cache arguments。
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
'TIMEOUT': 60,
'OPTIONS': {
'MAX_ENTRIES': 1000
}
}
}
整站缓存
在设置中添加中间件即可实现整站缓存,“update”中间件必须在第一个,“fetch”中间件必须在最后一个。该方法只适用于静态网站。
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
]
视图缓存
django.views.decorators.cache定义了一个cache_page装饰器,将缓存一个视图的响应。
from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def my_view(request):
...
cache_page有一个必填参数,缓存时限,单位为秒,为了便于理解,可以写成表达式形式,如上60 * 15即900秒。其他选填参数有cache:指定其他的缓存类型;key_prefix:指定键前缀。
在URL配置中使用缓存:
from django.views.decorators.cache import cache_page
urlpatterns = [
path('foo/<int:code>/', cache_page(60 * 15)(my_view)),
]
类视图不能直接使用cache_page装饰器,因为装饰器本质是个函数,接收函数并返回函数,所以只要把类视图转为函数就行。
# 在views.py中使用
class MyView(View):
...
my_view = cache_page(60 * 15)(MyView.as_view())
# 在urls.py中使用
urlpatterns = [
path('foo/<int:code>/', cache_page(60 * 15)(MyView.as_view())),
]
模板片段缓存
如果需要更多的控制,可以使用cache模板标记缓存模板片段。在模板的顶部放置{% load cache %},然后用{% cache %}标记需要缓存内容。它至少需要两个参数:缓存时限,以秒为单位,以及缓存片段的名称。例如:
{% load cache %}
{% cache 500 sidebar %}
.. sidebar ..
{% endcache %}
有时你可能想要根据片段中出现的一些动态数据,缓存不同的片段。例如,你可能想要为每个用户都缓存一个单独的副本。通过传递一个或多个参数,到{% cache %}模板标记来标记唯一的缓存片段:
{% load cache %}
{% cache 500 sidebar request.user.username %}
.. sidebar for logged in user ..
{% endcache %}
Cache API
Django还提供了一个简单的API,可以保存任意粒度的数据。你可以使用一个类似字典的对象,django.core.cache.caches,来访问缓存,这允许使用不同缓存方式:
from django.core.cache import caches
cache1 = caches['default']
cache2 = caches['others']
如果只有一个缓存默认的设置,使用from django.core.cache import cache获取默认缓存,这等于caches['default']。
基本的用法很简单:
>>> cache.set('my_key', 'hello, world!', 30)
>>> cache.get('my_key')
'hello, world!'
>>> # 等待 30 秒,'my_key'将过期...
>>> cache.get('my_key')
None
>>> # add()方法只添加不存在或失效的key,如果key仍有效则不会更新
>>> cache.set('add_key', 'Initial value')
>>> cache.add('add_key', 'New value')
>>> cache.get('add_key')
'Initial value'
>>> # 同时设置获取多对值
>>> cache.set('a', 1)
>>> cache.set('b', 2)
>>> cache.set('c', 3)
>>> cache.get_many(['a', 'b', 'c'])
{'a': 1, 'b': 2, 'c': 3}
>>> cache.set_many({'a': 1, 'b': 2, 'c': 3})
>>> cache.get_many(['a', 'b', 'c'])
{'a': 1, 'b': 2, 'c': 3}
>>> # 删除缓存
>>> cache.delete('a')
>>> cache.delete_many(['a', 'b', 'c'])
>>> cache.clear()
>>> # 关闭连接
>>> cache.close()
更多API见The low-level cache API。
本文介绍了Django Cache缓存系统的一些基础概念,但光看概念或许还是不会用,下一篇文章将结合实例介绍如何使用cache:Django Cache 缓存系统 —— 实例。
Django-redis 数据缓存
原文地址:https://www.jianshu.com/p/38f6155c2a2f 作者:清茶也醉人Q
Django中都支持什么样的缓存: 文件缓存 、 数据库缓存
同时从多张表查询得到数据——SQL消耗的资源较多
多张表查询到的数据,临时存储在一个缓存表中进行操作,如:视图view、软件缓存、memcache缓存、
redis缓存的操作
- 准备软件:redis数据库、django-redis模块
- 安装:pip install django-redis
- 配置:settings.py
CACHES = { "default": { "BACKEND": "django_redis.cache.RedisCache", "LOCATION": "redis://127.0.0.1:6379/1", "OPTIONS": { "CLIENT_CLASS": "django_redis.client.DefaultClient", } } }
(1)处理session[非必要,除非服务器空间有非常大的限制]:配置settings.py
SESSION_ENGINE = "django.contrib.sessions.backends.cache" SESSION_CACHE_ALIAS = "default"
(2)作为程序中数据的缓存使用
from django.core.cache import cache # 缓存中存储数据 cache.set(key, value, timeout=..) # 缓存中读取数据 v = cache.get(key)
一个关于缓存的django-redis项目案例
# 导入需要的模块 from django.core.cache import cache from . import models def cache_index(change=False): print('从redis中查询数据') a_list = cache.get('article_list') if a_list is None or change == True: print('去数据库中查找数据') a_list = models.Article.objects.all() print('将查询到的数据加载到缓存中') cache.set('article_list', a_list) return a_list

浙公网安备 33010602011771号