1-Django - 缓存

before

Django3.2 + win10 + python3.9

Django缓存框架的管档,写的很好,非常值得一读:https://docs.djangoproject.com/en/3.2/topics/cache/

Django缓存框架的核心目标:https://docs.djangoproject.com/en/3.2/misc/design-philosophies/#cache-design-philosophy

缓存的好处无需多言,所以Django提供了专门的缓存框架来支持各种缓存:

  • 不同的缓存粒度,推荐程度由高到低排序:
    • 指定视图缓存,粒度适中。
    • 模板片段缓存,对模板文件的局部内容进行缓存,粒度较细。
    • 全站缓存,粒度最大。
    • 更低级别的缓存API,用来缓存Python中的对象(list、dict、模型对象...),没用过,但在某些情况下(我暂时还没想到)很有用的样子。
  • 不同的缓存方式,推荐程度由高到低排序:
    • 第三方缓存数据库(redis、Memcache),专业的才是最好的嘛。另外,随着内存数据库的发展演变,Memcache不如redis用的多了。
    • 本地文件缓存,将渲染好的字符串缓存到文件中,下次查询省了渲染的步骤了,内存不大的小站点非常有用。
    • 本地数据库缓存,套路同本地文件缓存。
    • 本地内存缓存,内存大了啥都好说。
    • 虚拟缓存,用于开发,Django 带有一个实际上并不缓存的“虚拟”缓存——它只是实现了缓存接口而不做任何事情。

由于官档写的很详细了,本篇只做常用的配置和应用示例演示。

缓存配置

缓存参数

这里来列一下公共的缓存参数:

  • TIMEOUT:用于缓存的默认超时,以秒为单位。此参数默认为300秒(5 分钟)。您可以设置TIMEOUTNone,默认情况下,缓存键永不过期。值0会导致键立即过期(实际上是“不缓存”)。
  • OPTIONS:应该传递给缓存后端的任何选项。每个后端的有效选项列表会有所不同,第三方库支持的缓存后端会将其选项直接传递给底层缓存库。
    • MAX_ENTRIES:删除旧值之前缓存中允许的最大条目数。此参数默认为300
    • CULL_FREQUENCY:当缓存条目达到MAX_ENTRIES时,剔除缓存中的比例,这个值必须是整数,默认是3,即剔除三分之一,如果是即剔除一半。存疑的是剔除的策略,我只查到了基于本地内存的缓存剔除策略是LRU,其它的貌似都是随机剔除。
  • KEY_PREFIX: 一个字符串,将自动包含(默认添加)到 Django 服务器使用的所有缓存键中。
  • VERSION:Django 服务器生成的缓存键的默认版本号。
  • KEY_FUNCTION 一个字符串,其中包含一个函数的虚线路径,该函数定义了如何将前缀、版本和密钥组合成最终的缓存密钥。

redis

现在redis数据库用的较多,所以放到最上面!但是django的缓存框架中并没有实现.....但django-redis模块实现了,所以:

先下载django-redis模块:

pip install django-redis

然后在settings.py中进行配置:

CACHES = {
    "default": {
        "BACKEND": "django_redis.cache.RedisCache",
        # "LOCATION": "redis://IP:PORT/可选的数据库参数",
        # "LOCATION": "redis://127.0.0.1:6379/0",
        "LOCATION": "redis://127.0.0.1:6379",
        "OPTIONS": {
            "CLIENT_CLASS": "django_redis.client.DefaultClient",
            "CONNECTION_POOL_KWARGS": {
                "max_connections": 100
            },
            "DECODE_RESPONSES": True,  # True返回的数据自动decode
            "PASSWORD": "",  # 访问redis是否需要密码
        }
    }
}

具体的使用,参考:https://www.cnblogs.com/Neeo/articles/14269422.html

https://www.cnblogs.com/kai-/p/12403263.html

Memcache

现在由于Memcache用的不多了,这里仅作配置展示。

基于python-memcached模块连接memcache

settings.py中配置:

# 通过ip和port链接
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
        'LOCATION': '127.0.0.1:11211',
    }
}
# 通过sock文件链接
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',
        ]
    }
}

基于pylibmc模块连接memcache

settings.py中配置:

# 通过ip和port链接
CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
        'LOCATION': '127.0.0.1:11211',
    }
}
# 通过sock文件链接
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',
        ]
    }
}

本地内存缓存

在配置文件中进行配置即可:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',  # 唯一标识的key
    }
}

其他参数参考缓存参数章节。

本地文件缓存

在配置文件中进行配置即可:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
        'LOCATION': '/var/tmp/django_cache',
        # 如果您使用的是 Windows,请将驱动器号放在路径的开头
        # 'LOCATION': 'c:/foo/bar',
    }
}

其他参数参考缓存参数章节。

目录路径应该是绝对路径——也就是说,它应该从文件系统的根目录开始。是否在设置的末尾加上斜线并不重要。

确保此设置指向的目录存在并且可读可写,或者它可以由运行 Web 服务器的系统用户创建。

本地数据库缓存

在配置文件中进行配置即可:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
        'LOCATION': 'my_cache_table',
    }
}

与其他缓存后端不同,数据库缓存不支持在数据库级别自动剔除过期条目。相反,每次调用add()set()或时都会剔除过期的缓存条目。

完事之后,就要创建缓存表了:

python manage.py createcachetable

这将在您的数据库中创建一个表格,该表格具有 Django 的数据库缓存系统所期望的正确格式。表名取自 LOCATION

如果是多数据库的话,需要单独配置,参考管档吧:https://docs.djangoproject.com/en/3.2/topics/cache/#multiple-databases

虚拟缓存(用于开发)

项目中使用了缓存,但在开发和调试时,则希望跳过缓存,那么这个虚拟缓存就有用了,你只需要在配置文件中进行配置即可:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
    }
}

应用

这里以本地内存缓存作为缓存配置:

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',
        'OPTIONS': {
            'MAX_ENTRIES': 300,  # 最大缓存个数(默认300)
            'CULL_FREQUENCY': 3,  # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
        },
    }
}

局部视图缓存

settings.py中配置不变。

应用时有两种,分别是视图中以装饰器的形式和在路由上进行添加。

视图中应用缓存

views.py

import time
from django.shortcuts import render, HttpResponse, redirect
# 必须导入缓存装饰器
from django.views.decorators.cache import cache_page


@cache_page(5)  # 缓存单位是秒
def index(request):
    ctime = time.time()
    return HttpResponse(ctime)

urls.py

from django.contrib import admin
from django.urls import path, re_path
from app01 import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', views.index),
]

浏览器访问的话,每五秒才会刷新一次,因为缓存时间是5秒。

在路由中应用缓存

urls.py

from django.contrib import admin
from django.urls import path, re_path
from django.views.decorators.cache import cache_page
from app01 import views
urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', cache_page(5)(views.index)),
]

views.py

import time
from django.shortcuts import render, HttpResponse, redirect

def index(request):
    ctime = time.time()
    return HttpResponse(ctime)

浏览器访问效果跟上面的一样。

模板片段缓存

可以在模板中对局部进行更细粒度的缓存。

index.html

{% load cache %} <!-- 必须声明 -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>index</title>
</head>
<body>
<h3>未缓存的</h3>
{{ ctime }}
<h3>使用缓存</h3>
<!-- 缓存内容 -->
{% cache 5 'unique-snowflake' %}
    {{ ctime }}
{% endcache %}
</body>
</html>

urls.py不变:

from django.contrib import admin
from django.urls import path, re_path
from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('index/', views.index),
]

views.py也不变:

import time
from django.shortcuts import render, HttpResponse, redirect

def index(request):
    ctime = time.time()
    return render(request, 'index.html', {"ctime": ctime})

更多参考管档吧:https://docs.djangoproject.com/en/3.2/topics/cache/#template-fragment-caching

全栈缓存

全站缓存的配置需要用到中间件,settings.py

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',
]

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
        'LOCATION': 'unique-snowflake',
        'OPTIONS': {
            'MAX_ENTRIES': 300,  # 最大缓存个数(默认300)
            'CULL_FREQUENCY': 3,  # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
        },
    }
}
# 默认潮湿时间是300秒,我们可以通过CACHE_MIDDLEWARE_SECONDS来修改
CACHE_MIDDLEWARE_SECONDS = 5
# 下面两个是关于key的,保持默认就完了
CACHE_MIDDLEWARE_KEY_PREFIX = ""
CACHE_MIDDLEWARE_ALIAS = ""

see also: https://www.cnblogs.com/wupeiqi/articles/5246483.html

posted @ 2022-01-26 13:06  听雨危楼  阅读(245)  评论(0编辑  收藏  举报