django.cache缓存机制

为什么要引入缓存

对于网站来说,有一部分数据每当访问的时候都要从数据库中拿出来并计算,频繁的进行类似操作消耗较大,可以将这部分经常访问的数据缓存起来,提高效率,降低负载。

使用缓存过程可以这样描述:

1
2
3
4
5
6
7
given a URL, try finding that page in the cache
if the page is in the cache:
return the cached page
else:
generate the page
save the generated page in the cache (for next time)
return the generated page

设置缓存

缓存必须设置一个默认缓存:

1
2
3
4
5
{
'default': {
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
}
}

backend:

  • django.core.cache.backends.db.DatabaseCache
  • django.core.cache.backends.dummy.DummyCache
  • django.core.cache.backends.filebased.FileBasedCache
  • django.core.cache.backends.locmem.LocMemCache
  • django.core.cache.backends.memcached.MemcachedCache
  • django.core.cache.backends.memcached.PyLibMCCache

key:

1
2
def make_key(key, key_prefix, version):
return ':'.join([key_prefix, str(version), key])

Memcached

使用监听端口(python-memcached):

1
2
3
4
5
6
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': '127.0.0.1:11211',
}
}

使用socket文件(python-memcached):

1
2
3
4
5
6
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': 'unix:/tmp/memcached.sock',
}
}

如果使用的绑定是 pylibmc:

1
2
3
4
5
6
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
'LOCATION': '/tmp/memcached.sock',
}
}

memcached 有一个特点是可以在多个机器上运行,因此可以使用多个机器上的缓存:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11211',
]
}
}
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': [
'172.19.26.240:11211',
'172.19.26.242:11212',
'172.19.26.244:11213',
]
}
}

这个缓存是基于内存的,一旦系统奔溃,则缓存的数据也丢失了,因此数据不能仅仅依赖此缓存。

数据库缓存

使用一个table来进行数据缓存:

1
2
3
4
5
6
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
'LOCATION': 'my_cache_table',
}
}

创建缓存数据table:

1
python manage.py createcachetable

文件系统缓存

基于文件进行数据缓存:

1
2
3
4
5
6
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
}
}

伪缓存

在开发阶段,没有缓存设施但有不想因此改变代码,可以使用伪缓存,什么也不做,但提供了缓存接口,不引起代码报错:

1
2
3
4
5
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.dummy.DummyCache',
}
}

缓存参数

  • TIMEOUT:以秒计数,默认是300秒。如果设置为 None ,则表示缓存数据不超时过期。如果设置为0,则等同不缓存。
  • OPTIONS: 用于配置缓存后台
    • MAX_ENTRIES: 最大数据缓存数量,默认是缓存300条记录
  • KEY_PREFIX: 缓存数据key名字自动包含的内容

如:

1
2
3
4
5
6
7
8
9
10
CACHES = {
'default': {
'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
'LOCATION': '/var/tmp/django_cache',
'TIMEOUT': 60,
'OPTIONS': {
'MAX_ENTRIES': 1000
}
}
}

对站点缓存

增加配置:

1
2
3
4
5
MIDDLEWARE_CLASSES = [
'django.middleware.cache.UpdateCacheMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.cache.FetchFromCacheMiddleware',
]

对视图缓存

针对某个视图进行缓存:

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

在URLconf中指定视图缓存:

1
2
3
4
5
from django.views.decorators.cache import cache_page
urlpatterns = [
url(r'^foo/([0-9]{1,2})/$', cache_page(60 * 15)(my_view)),
]

缓存底层API

读取缓存

1
2
3
4
5
6
>>> from django.core.cache import caches
>>> cache1 = caches['myalias']
>>> cache2 = caches['myalias']
>>> cache1 is cache2
True
>>> from django.core.cache import cache # caches['default']

基本使用

接口:

  • set(key, value, timeout)
  • get(key)
  • add(key, value, timeout)
  • get_or_set(key, value, timeout)
  • set_many({key1:value1,key2:value2,…})
  • get_many([key1,key2,…])
  • incr()
  • decr()
  • delete(key)
  • delete_many([key1,key2,…])
  • clear()
  • close()

如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
>>> cache.set('my_key', 'hello, world!', 30)
>>> cache.get('my_key')
'hello, world!'
>>> cache.get('my_new_key') # returns None
>>> cache.get_or_set('my_new_key', 'my new value', 100)
'my new value'
>>> cache.set('num', 1)
>>> cache.incr('num')
2
>>> cache.incr('num', 10)
12
>>> cache.decr('num')
11
>>> cache.decr('num', 5)
6

使用Redis缓存

安装django-redis软件包后,相应缓存配置使用:

1
2
3
4
5
6
7
8
9
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": "redis://127.0.0.1:6379/1",
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
}
}
}

支持模式匹配:

1
2
3
>>> from django.core.cache import cache
>>> cache.keys("foo_*")
["foo_1", "foo_2"]

资料

吴羽舒 wechat
欢迎您扫一扫上面的微信公众号,订阅我的博客!