[关闭]
@orangleliu 2016-10-22T18:12:02.000000Z 字数 2171 阅读 3185

Django cache 模块笔记

django cache


cache是web必备的组件,django提供了很多层次的缓存,缓存views, 缓存结果,缓存整个网站等。

缓存介质

Cache层级

middleware

cache整个site,对 GETHEAD 类型请求缓存,相同URL不同参数认为是不同的请求,分别缓存。

对响应头的修改 Last-Modified Expires Cache-Control

!!使用中间件,注意书写顺序

decorators

主要用来对views设置缓存, 常用,也很好用

  1. from django.views.decorators.cache import cache_page
  2. @cache_page(60 * 15)
  3. def my_view(request):
  4. ...

60*15是按秒来计算,15分钟。这个装饰器,还有其他一些选项

  1. @cache_page(60 * 15, cache="special_cache")
  2. def my_view(request):
  3. ...

默认使用的是settings配置中 CACHES default 来缓存, 如果配置了多个缓存方式,可以指定为别的,这一点有点类似配置多个数据库。

  1. @cache_page(60 * 15, key_prefix="site1")
  2. def my_view(request):
  3. ...

还可以指定特殊的 key 前缀。

过期@cache_page中的key

cache_page装饰器很好用,但是有时候我们的信息实效性要求比较高,views中的数据更新了之后就需要赶紧告诉cache,这个views中的cache不可用了,来请求新的内容把。下面是解决的方案。

from expire-a-view-cache-in-django

这里的答案在新版本的django中可能不好使,请认真测试下。

template

模版中可以对部分block来cache,还可以设置对模版文件的cache,减少模版渲染的时间。

底层cache接口

这个就类似于最原始的cache逻辑了, get, set, delete, add, timeout等自己来控制。

  1. >>> from django.core.cache import cache
  2. >>> cache.set('name', 'lzz', 30)
  3. >>> cache.get('name') #30秒之后就无法获取了
  4. None
  5. >>> cache.get('name', 'orangle') #还可设置默认值
  6. 'orangle'

add和set的区别,set时候如果发现这个key已经存在,会覆盖原来的值,add时候如果发现key已经存在,不再更新已经有的值。

  1. >>> cache.set('age', 18)
  2. >>> cache.get('age')
  3. 18
  4. >>> cache.set('age', 25)
  5. >>> cache.get('age')
  6. 25
  7. >>> cache.add('age', 30)
  8. False
  9. >>> cache.get('age')
  10. 25

还可以 set get 不同的 version, 一些特殊的防止覆盖场景。

缓存 header

django设置http协议中的header来解决一些浏览器缓存的问题。

其他

Django自带的FileBasedCache逻辑

Django1.8 filecache源码

filesystem caching文档

  1. django cache key的默认格式,各个实现会有差别
  2. '%s:%s:%s' % (key_prefix, version, key)
  3. KEY_PREFIX 默认为 “”
  4. VERSION 默认为 1
  5. filecache怎么set get的呢?
  6. 假定配置用来cache的文件夹是 /cache/,如果检测到没有建立,会自动创建文件夹
  7. 对于每一个key会创建一个文件来存储
  8. set 逻辑
  9. 检查目录存在
  10. 根据key的到文件名(涉及到md5还有特殊的文件后缀)
  11. 根据需要清理空间来存放cache,文件名是key+文件后缀,文件内容是pickle之后的过期时间,和cache value
  12. tempfile 建立目录,写入临时文件(用到pickle zlib),文件移动到cache目录, 删除临时目录
  13. get 逻辑
  14. key的到文件名fname
  15. 如果文件存在判断是否过期
  16. 如果没有过期取出数据
  17. 怎么判断过期?
  18. set的时候过期时间写入到了cache文件中, _is_expired 中的 pickle.load(file) 这个方法用的真好。
  19. 怎么查找所有key?
  20. 使用 glob.glob1 根据后缀名来匹配,文件越多效率下降的越快
  21. 如果cachekey达到最大数目,并没有lru,而是随机选取删除

DiskCache

Django本身是支持filecache,这个是使用 SQLite和 filesystem来做cache,据说读性能好很多。 和其他cache方式综合一起来看,读性能一般水平,写入是非常慢的(甚至比Django自带的filecache要慢一些),特殊场景可以考虑下。

djangocache-benchmarks 列出来django cache生态中很多其他的项目, 看起来还算客观。

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注