@orangleliu
2016-10-22T18:12:02.000000Z
字数 2171
阅读 3185
django
cache
cache是web必备的组件,django提供了很多层次的缓存,缓存views, 缓存结果,缓存整个网站等。
cache整个site,对 GET
和 HEAD
类型请求缓存,相同URL不同参数认为是不同的请求,分别缓存。
对响应头的修改 Last-Modified
Expires
Cache-Control
!!使用中间件,注意书写顺序
主要用来对views设置缓存, 常用,也很好用
from django.views.decorators.cache import cache_page
@cache_page(60 * 15)
def my_view(request):
...
60*15
是按秒来计算,15分钟。这个装饰器,还有其他一些选项
@cache_page(60 * 15, cache="special_cache")
def my_view(request):
...
默认使用的是settings配置中 CACHES default
来缓存, 如果配置了多个缓存方式,可以指定为别的,这一点有点类似配置多个数据库。
@cache_page(60 * 15, key_prefix="site1")
def my_view(request):
...
还可以指定特殊的 key 前缀。
cache_page装饰器很好用,但是有时候我们的信息实效性要求比较高,views中的数据更新了之后就需要赶紧告诉cache,这个views中的cache不可用了,来请求新的内容把。下面是解决的方案。
from expire-a-view-cache-in-django
这里的答案在新版本的django中可能不好使,请认真测试下。
模版中可以对部分block来cache,还可以设置对模版文件的cache,减少模版渲染的时间。
这个就类似于最原始的cache逻辑了, get, set, delete, add, timeout等自己来控制。
>>> from django.core.cache import cache
>>> cache.set('name', 'lzz', 30)
>>> cache.get('name') #30秒之后就无法获取了
None
>>> cache.get('name', 'orangle') #还可设置默认值
'orangle'
add和set的区别,set时候如果发现这个key已经存在,会覆盖原来的值,add时候如果发现key已经存在,不再更新已经有的值。
>>> cache.set('age', 18)
>>> cache.get('age')
18
>>> cache.set('age', 25)
>>> cache.get('age')
25
>>> cache.add('age', 30)
False
>>> cache.get('age')
25
还可以 set get 不同的 version, 一些特殊的防止覆盖场景。
django设置http协议中的header来解决一些浏览器缓存的问题。
KEY_PREFIX
,避免开发测试环境的冲突
django cache key的默认格式,各个实现会有差别
'%s:%s:%s' % (key_prefix, version, key)
KEY_PREFIX 默认为 “”
VERSION 默认为 1
filecache怎么set 和 get的呢?
假定配置用来cache的文件夹是 /cache/,如果检测到没有建立,会自动创建文件夹
对于每一个key会创建一个文件来存储
set 逻辑
检查目录存在
根据key的到文件名(涉及到md5还有特殊的文件后缀)
根据需要清理空间来存放cache,文件名是key+文件后缀,文件内容是pickle之后的过期时间,和cache value
tempfile 建立目录,写入临时文件(用到pickle, zlib),文件移动到cache目录, 删除临时目录
get 逻辑
从key的到文件名fname
如果文件存在判断是否过期
如果没有过期取出数据
怎么判断过期?
set的时候过期时间写入到了cache文件中, _is_expired 中的 pickle.load(file) 这个方法用的真好。
怎么查找所有key?
使用 glob.glob1 根据后缀名来匹配,文件越多效率下降的越快
如果cache的key达到最大数目,并没有lru,而是随机选取删除
Django本身是支持filecache,这个是使用 SQLite和 filesystem来做cache,据说读性能好很多。 和其他cache方式综合一起来看,读性能一般水平,写入是非常慢的(甚至比Django自带的filecache要慢一些),特殊场景可以考虑下。
djangocache-benchmarks 列出来django cache生态中很多其他的项目, 看起来还算客观。