什么是缓存Cache

缓存是一类可以更快的读取数据的介质统称,也指其它可以加快数据读取的存储方式。
一般用来存储临时数据,常用介质的是读取速度很快的内存。
一般来说从数据库多次把所需要的数据提取出来,要比从内存或者硬盘等一次读出来付出的成本大很多。
对于中大型网站而言,使用缓存减少对数据库的访问次数是提升网站性能的关键之一。

为什么要使用缓存Cache

在Django中,当用户请求到达视图后,视图会先从数据库提取数据放到模板中进行动态渲染,渲染后的结果就是用户看到的网页。
如果用户每次请求都从数据库提取数据并渲染,将极大降低性能,不仅服务器压力大,而且客户端也无法即时获得响应。
如果能将渲染后的结果放到速度更快的缓存中,每次有请求过来,先检查缓存中是否有对应的资源,如果有,直接从缓存中取出来返回响应,节省取数据和渲染的时间,不仅能大大提高系统性能,还能提高用户体验。

Django内置缓存框架

  • 基于Memcached缓存(基本弃用)
  • 使用数据库进行缓存
  • 使用文件系统进行缓存
  • 使用本地内存进行缓存
  • 提供缓存扩展接口

Django如何使用Cache

  1. 在视图View中使用cache
    1
    2
    3
    4
    5
    from django.views.decorators.cache import cache_page

    @cache_page(60 * 15)
    def my_view(request):
    ...
  2. 在路由URLConf中使用
    1
    2
    3
    4
    5
    6
    from django.views.decorators.cache import cache_page

    urlpatterns = [
    path('foo/<int:code>/', cache_page(60 * 15)(my_view)),
    ]
    ...
  3. 在模板中使用cache
    1
    2
    3
    4
    {% load cache %}
    {% cache 500 sidebar request.user.username %}
    .. sidebar for logged in user ..
    {% endcache %}

Django缓存配置–使用数据库缓存

  1. 创建缓存表
    python manage.py createcachetable [table_name]
  2. 配置缓存
    在项目的 settings.py 文件中创建 CACHES 配置项
    1
    2
    3
    4
    5
    6
    7
    8
    CACHES = { 
    'default':
    {
    'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
    'LOCATION': 'my_cache_table', # 数据库表名
    'TIMEOUT': 60 * 5, # 超时时间
    }
    }

默认缓存

  1. 装饰器
    @cache_page(30) 超时时间30秒
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @cache_page(30)
    def news(request):
    news_list = []

    for i in range(10):
    news_list.append("最近贸易战又开始了%d" % i)

    sleep(5)

    data = {
    'news_list': news_list
    }
    response = render(request, 'news.html', context=data)
    return response
  2. 手动
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    def news(request):
    result = cache.get("news")

    if result:
    return HttpResponse(result)

    news_list = []

    for i in range(10):
    news_list.append("最近贸易战又开始了%d" % i)

    sleep(5)

    data = {
    'news_list': news_list
    }
    response = render(request, 'news.html', context=data)

    cache.set("news", response.content, timeout=60)

    return response

Reidis缓存

  1. 启动Redis
  2. 更改settings.py中Cache配置
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    CACHES = { 
    'default':
    {
    # 指定通过django-redis接入Redis服务
    'BACKEND': 'django_redis.cache.RedisCache',
    # Redis服务器的URL 本机
    'LOCATION': ['redis://127.0.0.1:6379/1', ],
    # Redis中键的前缀(解决命名冲突)
    # 'KEY_PREFIX': 'vote',
    # 其他的配置选项
    'OPTIONS': {
    'CLIENT_CLASS': 'django_redis.client.DefaultClient',
    # 连接池(预置若干备用的Redis连接)参数
    'CONNECTION_POOL_KWARGS': {
    # 最大连接数
    'max_connections': 512,
    },
    # 连接Redis的用户口令
    # 'PASSWORD': 'foobared',
    }
    }
    }
    随后可在redis中查询到存储的数据

多缓存同时使用

  1. 更改settings.py中Cache配置,同时设定default和redis_backend两个
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    CACHES = {
    'default': {
    'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
    'LOCATION': 'my_cache_table',
    'TIMEOUT': 60 * 5,
    # 'OPTIONS': {‘MAX_ENTRIES’: ‘300’},
    # 'KEY_PREFIX': ‘rock’,
    # 'VERSION'': ‘1’,
    #
    },
    'redis_backend': {
    # 指定通过django-redis接入Redis服务
    'BACKEND': 'django_redis.cache.RedisCache',
    # Redis服务器的URL 本机
    'LOCATION': ['redis://127.0.0.1:6379/1', ],
    # Redis中键的前缀(解决命名冲突)
    # 'KEY_PREFIX': 'vote',
    # 其他的配置选项
    'OPTIONS': {
    'CLIENT_CLASS': 'django_redis.client.DefaultClient',
    # 连接池(预置若干备用的Redis连接)参数
    'CONNECTION_POOL_KWARGS': {
    # 最大连接数
    'max_connections': 512,
    },
    # 连接Redis的用户口令
    # 'PASSWORD': 'foobared',
    }
    }
    }
  2. 装饰器——cache可为defult或redis_backend
    1
    2
    3
    4
    5
    @cache_page(60, cache='redis_backend')
    def jokes(request):

    sleep(5)
    return HttpResponse('Jokelist')
  3. 手写——选择缓存库,可为defult或redis_backend
    1
    2
    3
    4
    5
    from django.core.cache import cache, caches

    def news(request):
    cache = caches['redis_backend']
    result = cache.get("news")