文章目录
一,缓存
二,缓存类型及配置
django提供了几种不同的缓存方式,下面是对所有缓存可用值的解释。
1,Memcached
Memcached是Django本地支持的速度最快、效率最高的缓存类型,它完全是一个基于内存的缓存服务器,最初是为处理LiveJournal.com的高负载而开发的,后来由Danga Interactive开源。Facebook和Wikipedia等网站使用它来减少数据库访问并显著提高网站性能。
Memcached作为守护进程运行,并分配了指定数量的RAM。它所做的只是提供一个快速接口,用于在缓存中添加、检索和删除数据。所有数据都直接存储在内存中,因此不存在数据库或数据库的开销。
Memcached是一个高性能分布式内存对象缓存系统,通过在内存中缓存数据与对象减少读取数据库的次数,从而提高动态网站响应速度,实现动态网站减轻数据库系统负载。
适用于超大型网站。
- Set
BACKEND
todjango.core.cache.backends.memcached.MemcachedCache
ordjango.core.cache.backends.memcached.PyLibMCCache
- Set
LOCATION
toip:port
使用时需要安装Memcached服务器,并通过python-memcached 与 pylibmc进行调用,
CACHES = {
# 默认缓存数据表
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', #必须项 或使用django.core.cache.backends.memcached.PyLibMCCache
'LOCATION': '127.0.0.1:11211', #必须项 或使用'unix:/tmp/memcached.sock' 使用PyLibMCCache时不需要unix:前缀。
}
}
Memcached的一个
优秀特性
是它能够在多个服务器上共享缓存。这意味着您可以在多台机器上运行Memcached守护进程,并且程序将把这组机器视为单个缓存,而不需要在每台机器上重复缓存值。要利用此特性,请在位置上包括所有服务器地址。
以分号或逗号分隔的字符串或列表的形式:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}
关于Memcached的最后一点是基于内存的缓存有一个
缺点
:由于缓存的数据存储在内存中,因此如果服务器崩溃,数据将丢失。
显然,内存不是用于永久数据存储的,因此不要依赖基于内存的缓存作为唯一的数据存储。
毫无疑问,任何Django缓存后端都不应该用于永久存储,它们都旨在作为缓存而非存储的解决方案。
2,数据库缓存
Django可以将其缓存的数据存储在您的数据库中。 如果您拥有快速索引良好的数据库服务器,则此方法效果最佳。
适合中大型网站。
- Set
BACKEND
todjango.core.cache.backends.db.DatabaseCache
- Set
LOCATION
totablename
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache', #必须项
'LOCATION': 'my_cache_table', #必须项 该名称可以是您想要的任何名称,只要它是数据库中尚未使用的有效表名即可。
}
}
1,创建缓存表
在使用数据库缓存之前,必须使用此命令创建缓存表:python manage.py createcachetable
这将在数据库中创建一个表,该表的格式符合Django的数据库缓存系统的要求。表的名称取自LOCATION
。
2,使用多个数据库
如果使用多个数据库缓存,则createcachetable
会为每个缓存创建一个表。像数据迁移一样,createcachetable
不会触及现有表。 它只会创建丢失的表。
如果使用多个数据库,则createcachetable
据数据库路由器的allow_migrate()方法进行路由。为了进行路由,数据库高速缓存表在名为django_cache
的应用程序中显示为名为CacheEntry
的模型。 该模型不会出现在模型缓存中,但是可以将模型详细信息用于路由目的。
如果要打印将要运行的SQL,而不是运行它,请使用createcachetable --dry-run
选项。
以下路由器会将所有缓存读取操作定向到cache_replica,并将所有写入操作定向到cache_primary。 缓存表将仅同步到cache_primary上:
class CacheRouter:
"""A router to control all database cache operations"""
def db_for_read(self, model, **hints):
"All cache read operations go to the replica"
if model._meta.app_label == 'django_cache':
return 'cache_replica'
return None
def db_for_write(self, model, **hints):
"All cache write operations go to primary"
if model._meta.app_label == 'django_cache':
return 'cache_primary'
return None
def allow_migrate(self, db, app_label, model_name=None, **hints):
"Only install the cache model on primary"
if app_label == 'django_cache':
return db == 'cache_primary'
return None
3,文件系统缓存
基于文件的后端序列化并将每个缓存值存储为单独的文件。
适合中小型网站。
- set
BACKEND
todjango.core.cache.backends.filebased.FileBasedCache
- set
LOCATION
toa suitable directory
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', #必须项
'LOCATION': '/var/tmp/django_cache', #必须项 必须保证服务器对列出的路径具有读写权限。
}
}
如果使用的是Windows,需要引用完整路径:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
}
}
4,本地内存缓存
django默认的缓存方式。在无条件使用memcached,需要内存缓存的情况下使用local-memory缓存,此内存是多线程,线程安全。
只适用于开发与测试。
- set
BACKEND
todjango.core.cache.backends.locmem.LocMemCache
- set
LOCATION
toa suitable directory
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', #必须项
'LOCATION': 'unique-snowflake', #非必须项 用于标识各个内存存储区。如果只有一个locmem缓存,可以省略该位置;但是,如果您有一个以上的本地内存缓存,则需要为其中至少一个指定名称,以便将它们分开。
}
}
使用本地内存缓存有一个明显
缺点
:每个进程都有自己的私有缓存实例,这意味着不可能进行跨进程缓存。这显然还意味着本地内存缓存的内存效率不是特别高,因此它可能不是生产环境的好选择。这有利于发展。
5,虚拟缓存
Django带有一个“虚拟”缓存,该缓存实际上并没有缓存-它只是实现了缓存接口,而不做任何事情。
如果生产站点在各个地方都使用了重型缓存,但是在开发/测试环境中却不想缓存并且不想将代码更改为后者的特殊情况,这将非常有用。
- set
BACKEND
todjango.core.cache.backends.dummy.DummyCache
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache', #必须项
}
}
6,使用自定义的缓存后台
尽管Django开箱即用地支持许多缓存后端,但有时可能希望使用自定义的缓存后端:要将外部缓存后端与Django一起使用。
适合需要使用外部的缓存系统的情况。
- set
BACKEND
topath.to.backend
如使用redis缓存:
1.安装依赖 pip install django-redis
2.在stting中配置CACHES,可以设置多个缓存,根据名字使用
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379", #如果redis server设置了密码,需要使用‘密码@redis://127.0.0.1:6379’
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
"CONNECTION_POOL_KWARGS": {"max_connections": 100}
}
}
},
#另添加缓存
"JERD": { }
3.根据名字去连接池中获取连接
from django_redis import get_redis_connection
conn = get_redis_connection("default")
缓存还有多个可选参数:见官方文档Cache arguments部分。
三,缓存使用示例
1,缓存类型选择与配置
示例使用数据库缓存:
CACHES = {
# 默认缓存数据表
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'my_cache_table',
'TIMEOUT': 60, # TIMEOUT设置缓存的生命周期,以秒为单位,若为None,则永不过期
'OPTIONS': {
'MAX_ENTRIES': 1000, # MAX_ENTRIES代表最大缓存记录的数量
'CULL_FREQUENCY': 3, # 当缓存到达最大数量之后,设置剔除缓存的数量
}
},
# 设置多个缓存数据表
'MyDjango': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'MyDjango_cache_table',
}
}
还要创建缓存数据表:
python manage.py createcachetable
2,选择缓存的使用方式
1,全站缓存The per-site cache
一旦设置好了缓存,使用缓存的最简单方法就是缓存整个站点。
添’django.middleware.cache.UpdateCacheMiddleware
‘与’django.middleware.cache.FetchFromCacheMiddleware
’ 到MIDDLEWARE
设置中。
MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
......
'django.middleware.cache.FetchFromCacheMiddleware',
]
然后,将以下必需设置添加到Django配置文件中:
CACHE_MIDDLEWARE_ALIAS = "default" 用于存储的缓存路径.
CACHE_MIDDLEWARE_SECONDS = 15 每个页面的缓存秒数.
CACHE_MIDDLEWARE_KEY_PREFIX = "MyDjango" 指定唯一站点名称,在基于分布式部署的访问流量分配基础上,区分服务器的缓存数据。
视图与模板:
index/views.py:
def index(request):
return render(request, 'index.html')
templates/index.html:
<html>
<body>
<div>
<div>Hello Django</div>
</div>
</body>
</html>
访问任意页面都会在my_cache_table中生成相应缓存:
虽然易于使用,但存在
缺点
:如果网站规模比较大,则相应的缓存数据会多很多,就会对缓存系统施加很大压力。不推荐使用。
2,视图缓存The per-view cache
使用缓存框架的更精细的方法是缓存单个视图的输出。
当用户发出请求时,如果请求的视图函数已产生缓存,则以缓存数据作为响应,从而减少请求处理的资源与时间消耗。
django.views.decorators.cache定义了一个cache_page装饰器,它将自动缓存视图的响应。 易于使用。
视图与模板:
from django.shortcuts import render
from django.views.decorators.cache import cache_page
# 参数cache与配置属性CACHE_MIDDLEWARE_ALIAS相同
# 参数key_prefix与配置属性CACHE_MIDDLEWARE_KEY_PREFIX相同
# 参数timeout与配置属性CACHE_MIDDLEWARE_SECONDS相同
# CACHE_MIDDLEWARE_SECONDS的优先级高于参数timeout
@cache_page(timeout=10, cache='MyDjango', key_prefix='MyView')
def index(request):
return render(request, 'index.html')
templates/index.html:
<html>
<body>
<div>
<div>Hello Django</div>
</div>
</body>
</html>
访问指定页面都会在MyDjango中生成相应缓存:
3,路由缓存Specifying per-view cache in the URLconf
是一种特殊的视图缓存,但与视图缓存在工作过程上有所不同。
路由与模板:
from django.urls import path
from . import views
from django.views.decorators.cache import cache_page
urlpatterns = [
# 网站首页设置路由缓存
path('1', cache_page(timeout=10, cache='MyDjango', key_prefix='MyURL')(views.index), name='index'),
path('2', views.index, name='index'),
]
templates/index.html:
<html>
<body>
<div>
<div>Hello Django</div>
</div>
</body>
</html>
- 当两个路由指向同一视图函数时,路由缓存会在访问视图函数之前判断该路由是否已产生缓存进而判断是否要访问。
4,模板缓存Template fragment caching
对模板中的一部分数据设置缓存,如对header设置缓存。
视图与模板:
def index(request):
return render(request, 'index.html')
<html>
<body>
<div>
{# 设置模版缓存 #}
{% load cache %}
{# 10代表生命周期 #}
{# MyTemp代表缓存数据的cache_key字段 #}
{# using="MyDjango"代表缓存数据表 #}
{% cache 10 MyTemp using="MyDjango" %}
<div>Hello Django</div>
{# 缓存结束 #}
{% endcache %}
</div>
</body>
</html>