Django 框架意识:配备强大的缓存系统
动态网站的基本权衡是它们是动态的。每当用户请求页面时,Web 服务器都会执行各种计算(从数据库查询到模板呈现再到业务逻辑)以创建访问者看到的页面。从处理成本的角度来看,这比从文件系统读取文件的标准服务器布置要昂贵得多。对于中高流量的网站,必须尽可能减少开销。这就是缓存发挥作用的地方。
缓存是为了保存昂贵的计算结果,这样你下次就不用再计算它们了。下面是一些伪代码,解释了如何在动态生成的网页中使用此方法: Django带有一个强大的缓存系统,允许为每个请求计算动态页面。为了方便起见,Django 提供了不同级别的缓存粒度。您可以缓存特定视图、仅缓存难以生成的部分或缓存整个站点。 缓存系统需要进行少量设置。也就是说,您需要告诉它缓存的数据应该放置在哪里 - 是在数据库中、在文件系统中还是直接在内存中。这是一个影响缓存性能的重要决定;是的,某些缓存类型比其他类型更快。 缓存设置点位于配置文件的缓存配置中。这里有缓存配置的所有可用值的描述。 Memcached 是一个完全基于内存的缓存服务器。它是 Django 原生支持的最快、最高效的缓存类型。它最初是为了处理 LiveJournal.com 的高负载而开发的,然后由 Danga Interactive 开放。 。 Facebook 和维基百科等网站使用它们来减少数据库访问并显着提高网站性能。 Memcached 作为守护进程运行,并分配指定数量的 RAM。它所做的只是提供一个快速界面来添加、检索和删除缓存中的数据。所有数据都直接存储在内存中,因此没有数据库开销或文件系统使用。 安装 Memcached 本身后,您需要安装 Memcached 绑定。有多种可用的 Python Memcached 绑定; Django 支持的两个是 pylibmc 和 pymemcache。 在 Django 中使用 Memcached: Memcached运行在localhost(127.0.0.1)端口11211,使用 Memcached❀Memcached❀❀x文件可以通过本地me访问mcached.sock 给出一个 URL,尝试找到此缓存页面
如果该页面已缓存:
返回缓存页面
使用 @cache_page(60 * 15, key_prefix="site1")
def my_view(request):
...
否则:
生成页面
缓存生成的页面(下次)
返回生成的页面
设置缓存
Memcached
将 BACKEND
设置为 django.core.cache.backends.memcached.PyMemcache 或Cache django.core.cache.backends.memcached。 PyLibMCCache (取决于您选择的 memcached 绑定)。 LOCATION
设置为 ip:port
值,其中 ipipDem 是 M 地址 端口
正在运行 Memcached 端口,或者设置为 unix:path
值,其中 path
是 Memcached Unix 套接字文件的路径。 pymemcache
绑定:CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
'LOCATION': '127.0.0.1:11211',
}
}
pymemcache
绑定:
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
'LOCATION': 'unix:/tmp/memcached.sock',
}
}
Memcached 有一个很好的功能,它可以在多个服务器上共享缓存。这意味着您可以在多台计算机上运行 Memcached 守护进程,并且该程序会将这组计算机视为单个 缓存,而无需在每台计算机上复制缓存值。要利用此功能,请将所有服务器地址包含在 缓存由在 IP 地址 172.19.26.240 和 172.19.26.242 上运行的 Memcached 实例共享,两者均在端口 11211 上: 缓存由 Memcached 2.1.2.1 共享。 Memcached 实例共享的 172.19.26.242(端口 11212)、172.19.26.242(端口 11212)和 172.19.26.244(端口 11213): 基于内存的缓存有一个缺点:因为当服务器崩溃时,缓存的数据存储在内存中。内存并不是为了永久存储数据而设计的,因此不要依赖基于内存的缓存作为唯一的数据存储。 Django 3.2 添加了 自版本 3.2 起已删除 MemcachedCache`后端已被删除,因为 Django 可以将缓存数据存储在数据库中。如果您有一个快速、索引良好的数据库服务器,这种类型的缓存效果最好。 使用数据库表作为缓存后端: 本例中缓存表的名称为 缓存,在使用数据库之前,必须先创建Use数据库。 表的格式表名称为 如果您使用多个数据库缓存, 如果在多个数据库中使用缓存,则必须为数据库缓存表设置路由指令。数据库缓存表在 例如,以下路径可以将所有缓存读取操作定向到 如果未指定指向数据库缓存模型的路径,则缓存后端使用 基于文件的后端将每个缓存值序列化并将其存储为文件。您可以将 BACKEND 如果您有 Windows -system,将盘符放在路径的开头,如下: 目录路径为绝对路径。确保配置指向的目录存在,并且可以被运行Web服务器的系统用户读写,或者可以由运行Web服务器的系统用户直接创建。 如果配置文件中未指定其他缓存,则这是默认缓存。您可以将 BACKEND 设置为 在 缓存参数 每个缓存后端都可以通过附加参数控制缓存行为。这些参数作为 实施自己的缓存策略的缓存后端(即 Memcached 客户端传递Content后 请参阅缓存文档以获取更多信息。 请参阅缓存文档以获取更多信息。 请参阅缓存文档以获取更多信息。 配置文件系统后端,超时为 60 秒,最大容量为 1000 个项目: 一旦设置了缓存,使用缓存的最简单方法就是缓存整个站点。将 最后,在 Django 设置文件中添加以下所需配置: 使用缓存视图结果的常见方法是缓存视图结果。 与缓存站点一样,视图也会被缓存,以 URL 为键。如果多个 URL 指向同一个视图,则每个 URL 会单独缓存。继续 将 my_view 那么 您可以基于每个视图设置缓存 -Override 前缀。 此外, 如果您在 URLconf 中使用 包含 缓存过期时间可以是模板变量,只要模板变量解析为整数值即可。例如,如果模板变量 为了避免模板中的重复,您可以在某处设置缓存过期时间重用这个值。 默认情况下,缓存标签首先尝试使用名为“template_fragments”的缓存。如果该缓存不存在,则会回退到默认缓存。您可以选择与 LOCATION
中,以分号或逗号分隔的字符串或列表的形式。CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyMemcacheCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11212',
'172.19.26.244:11213',
]
}
}
PyMemcacheCache
后端。 python-memcached
设置为 存在一些问题且未维护。请改用
设置为 PyMemcacheCache
或 PyLibMCCache
。 数据库缓存
BACKEND
设置为django.core.cache.Databas❝LOCATION
设置为表名
来自数据库表。该表名可以是任何符合要求的未使用的名称。 my_cache_table
: CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_cache_table',
}
}
创建缓存表¶
LOCATION
,正如Django数据库缓存系统所期望的那样。 createcachetable
为每个缓存创建一个表。使用多个数据库时,createcachetable
观察数据库路由器的allow_migrate()
方法。与 migrate
一样,createcachetable
不会影响现有表,它只会创建丢失的表。 多个数据库
django_cache
应用程序中显示为 CacheEntry
的模型名称。 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
默认
数据库。 文件系统缓存
"django.core.cache.backends.filebased.FileBasedCache"
并将 "django.core.cache.backends.filebased。基于文件的缓存" "将
和 放在 ❀ LOAD 上 例如,要将缓存数据存储在 /var/tmp/django_cache
,请使用以下配置: CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
}
}
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': 'c:/foo/bar',
}
}
本地内存缓存
"django.core.cache.backends.locmem.LocMemCache"
。例如:CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
'LOCATION': 'unique-snowflake',
}
}
LOCATION
用于标识每个内存存储。如果只有一个 locmem
缓存,可以忽略 LOCATION
如果有多个本地内存缓存,请至少为其中一个命名以区分它们。使用自定义缓存后端
CACHES♿❓配置中使用Python导入路径作为
设置为 BACKEND
。 ,如下所示: CACHES = {
'default': {
'BACKEND': 'path.to.backend',
}
}
CACHES
配置中的附加键提供。有效参数如下: TIMEOUT
:默认缓存超时时间,单位为秒。此参数默认为 300
秒(5 分钟)。您可以将 TIMEOUTNone
,以便缓存密钥默认永不过期。值 0
将使密钥立即过期(实际上“不缓存”)。 OPTIONS
:传递到缓存后端的所有选项。有效选项列表随每个后端而变化,第三方库支持的缓存后端将其选项直接传递到底层缓存库。 locmem
、文件系统和s)遵循以下选项:
OPTIONS
作为客户端构造函数的关键字参数,允许对客户端行为进行更高级的控制。请参见具体用途如下。 MAX_ENTRIES
:删除旧值之前缓存中允许的最大条目数。默认为 300
。 CULL_FREQUENCY
:达到MAX_ENTRIES
时将删除的条目比例。实际比率为 1 / CULL_FREQUENCY
,因此将 CULL_FREQUENCY
设置为 2
,这样当 ENT 达到 时,就会删除一半的条目。该参数应该是一个整数,默认为3
。值 CULL_FREQUENCY
为 0
,这意味着当达到 MAX_ENTRIES
时,将转储整个缓存。在某些后端(尤其是数据库
),这使得缓存更快,但代价是更多缓存未命中。 KEY_PREFIX
。自动包含在 Django 服务器使用的所有缓存键中的字符串(默认为前缀)。 VERSION
:Django 服务器生成的缓存键的默认版本号。 KEY_FUNCTION
一个字符串,带有点分隔的函数路径,该函数定义如何将前缀、版本和密钥组合成最终的缓存密钥。 CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
'TIMEOUT': 60,
'OPTIONS': {
'MAX_ENTRIES': 1000
}
}
}
站点缓存
MIDDLEWARE
添加到 'django.middleware.cache.UpdateCacheMiddleware'
和 'djan.chrom'le'djan。 ,如下:
视为举个例子,如果你的 URLconf 是这样的: MIDDLEWARE = [
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
]
CACHE_MIDDLEWARE_ALIAS
-- 用于存储的缓存别名。 CACHE_MIDDLEWARE_SECONDS
- 每个页面应缓存的秒数。 CACHE_MIDDLEWARE_KEY_PREFIX
-- 如果您使用相同的 Django 安装来跨多个站点共享缓存,请设置将此值设置为站点名称,或将其设置为 Django 实例中唯一的另一个字符串以避免键冲突。 。如果你不在乎,可以将其设置为空字符串。 FetchFromCacheMiddleware
如果请求和响应标头允许,缓存状态为 200 的 GET 和 HEAD 响应。对具有不同请求参数的同一 URL 的请求的响应被视为单独的页面并单独缓存。该中间件期望 HEAD 请求与相应的 GET 请求具有相同的响应标头;在这种情况下,它可能会返回 HEAD 请求的缓存 GET 响应。 view 视图缓存
django.views.decorators.cache.
cache_page
()¶django.views.decorators.cache
定义了cache_page
装饰器,它将自动缓存视图的响应:❀_page:缓存使用参数时间,以秒为单位。在上面的示例中,my_view()
视图的结果缓存了 15 分钟。 (请注意,为了便于阅读,我们将其写为 60 * 15
。由 cache_page
设置的缓存超时优先于 Cache 中的“Max-Age”指令-Control
header. urlpatterns = [
path('foo/<int:code>/', my_view),
]
/foo/1/
//3 是请求被单独缓存,正如你所期望的那样,但是。如果 URL 的一部分 (例如 /foo/23/
) 被请求,后续请求将使用缓存。 获取用于特定缓存的装饰(从 Caches 设置)默认情况下使用默认缓存,但您可以指定所需的任何缓存:
@cache_page(60 * 15, cache="special_cache")
def my_view(request):
...
cache_page
传递可选关键字参数 key_prefix
,其工作方式与中间件CACHE_KEY_MIDDLEWARE_IX。 您可以像这样使用它:
@cache_page(60 * 15, key_prefix="site1")
def my_view(request):
...
key_prefix
于 cache
参数可能需要一起指定。参数key_prefix
和CACHES
下指定的KEY_PREFIX
已连接。cache_page
自动降低在响应 ching 中过期的 缓存控制
和 和
响应。
模板标签(tag)用来缓存模板片段。要使模板可以访问此标签,请将 指定 URLconf 缓存中的视图
cache_page
,您可以像这样包装视图函数。例如,urlpatterns = [
path('foo/<int:code>/', my_view),
]
my_view
和cache_page
:❙模板❙❙❙❙cache cache使用{% load cache %}
放在模板顶部。 {% cache %}
模板标签会缓存片段内容一段时间。它至少需要两个参数:缓存老化时间(以秒为单位)和缓存片段的名称。如果缓存过期时间设置为None
,则片段将永久存储在缓存中。该名称不能是变量名。例如: {% load cache %}
{% cache 500 sidebar %}
.. sidebar ..
{% endcache %}
my_timeout
设置为 600
,则以下两个示例是相同的: {% cache 600 sidebar %} ... {% endcache %}
{% cache my_timeout sidebar %} ... {% endcache %}
using
关键字参数一起使用的备用缓存后端,该参数必须是标记的最后一个参数。 {% cache 300 local-thing ... using="localcache" %}
版权声明
本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。
发表评论:
◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。