缓存主要用来加速慢存储的访问效率,减少对数据库的操作,提升页面访问速度。
yum install epel-releas # 添加 EPEL 仓库
yum update # 更新 yum 源yum -y install redis
systemctl start redis # 启动 redis 服务
配置可远程连接 Redis
修改配置文件:/etc/redis.conf
:
# 找到 `bind 127.0.0.1`,注释掉这一行# 将 protected-mode 修改为 no
protected-mode no# 保存重启 `redis` 服务
systemctl restart redis
Django
中可以配置多种缓存源,支持的缓存设置有:
memcached
缓存redis
缓存内存缓存
local-memory-caching
,线程安全的,进程间独立,即每个进程一份缓存,Django
默认配置,配置示例如下:
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.locmem.LocMemCache','LOCATION': 'unique-snowflake',}
}
文件缓存
filesystem caching
,将数据缓存到文件系统中,配置示例如下:
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.filebackend.FileBaseCache','LOCATION': '/var/tmp/django_cache',}
}
数据库缓存
database caching
,需要创建缓存用的表,意义不大,不推荐使用,配置示例如下:
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.db.DataaseCache','LOCATION': 'my_cache_table',}
}
memcached
Django
推荐的缓存系统,也是分布式的(分布式逻辑在客户端),Django
内置支持,集成度比较好,配置示例如下:
CACHES = {'default': {'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache','LOCATION': ['172.19.26.240:11211','172.19.26.242.11211',],}
}
redis 缓存
使用 redis
缓存有两种思路:
Django
模块:django-redis
或 django-redis-cache
Redis
包操作 Redis
,不使用 Django
模块,缺点是无法使用内置缓存模块的接口,不推荐安装
pip install django-redis==4.9.0
pip install hiredis
默认安装的 redis
是最新版,使用缓存时可能会报错:redis.exceptions.DataError: Invalid input of type: 'CacheKey'.
,可将版本降为 2.10.6
:
pip install redis==2.10.6
hiredis
的作用是提升 redis
解析性能,具体测试结果可在 https://github.com/redis/hiredis-py#benchmarks
配置
配置 Projects/settings.py
:
# Redis 缓存REDIS_URL = 'redis://192.168.131.131:6379/1'CACHES = {'default': {'BACKEND': 'django_redis.cache.RedisCache','LOCATION': REDIS_URL,'TIMEOUT': 300,'OPTIONS': {'CLIENT_CLASS': 'django_redis.client.DefaultClient','PASSWORD_CLASS': 'redis.connection.HiredisParser',},'CONNECTION_POOL_CLASS': 'redis.connection.BlockingConnectionPool',}
}
使用缓存首先要知道在哪缓存、缓存什么,即使用场景,千万不要以为缓存一定能优化访问效率,一定要先知道项目的业务特点。
Django
提供的各种粒度的缓存方案:
整站缓存
配置 settings
中间件:
MIDDLEWARE = [
# 站点缓存 , 注意必须在第一个位置
'django.middleware.cache.UpdateCacheMiddleware',
...
# 站点缓存, 注意必须在最后一个位置
'django.middleware.cache.FetchFromCacheMiddleware',]
若内容在缓存中存在,则使用 FetchFromCacheMiddleware
获取内容并返回,在返回之前,判断缓存中是否已存在,若不存在则 UpdateCacheMiddleware
会将缓存保存至缓存,从而实现全站缓存。
单页面缓存
from django.shortcuts import render, HttpResponse
import time
from django.views.decorators.cache import cache_page@cache_page(60 * 15)
def index(request):ctime = str(time.time())return render('index.html', locals())
局部数据缓存
class BookListView(View):"""书籍列表"""def get(self, request):res = {"code": 0, "msg": "查询成功", "data": []}book_list = cache.get('book_list')if not book_list:book_list = models.Book.objects.all()cache.set('book_list', book_list, 10 * 60)res["data"] = json.loads(serializers.serialize("json", book_list))return JsonResponse(res)
首先从缓存中获取数据,若不存在则从数据库取出,并放入缓存中,以便下次使用。
URLconf 中使用缓存
场景:多个 URL
指向同一视图函数,但只想缓存一部分 URL
:
from django.views.decorators.cache import cache _page
urlpatterns = [url(r'^foo/([0-9]{1,2})/$',cache_page(60 * 15)(index)),url(r'^$', cache_page(60 * 30)(IndexView.as_view()), name='order'),]
URL
缓存缓存的也是整个页面,需要考虑是否整个页面都应该缓存。
模板页面(局部页面)缓存
模板中使用缓存时比较推荐的一种方式,可以充分利用缓存粒度,可保证只缓存那些适合缓存的 HTML
片段:
{% load cache %}
Myblog
测试redis
非缓存地段
{% cache 10 aabbcc %}这里缓存
{% endcache %}
在配置好后,应用之前可以先用 Django shell
测试是否能够成功:
python manage.py shellfrom django.core.cache import cachecache.set('book_list', '流畅的 Python', 60 * 60)
cache.has_key('book_list')
cache.get('book_list)
HTML
片段,使用缓存可以减少多次重复操作参考文章