Django Cache

Django本身就带有一个强大的缓存系统,提供不同级别的缓存粒度:可以缓存特定的视图,也可以只缓存部分模板片段,还可以缓存整个网站。但这几类都不是我想要的,本篇文章不会介绍以上几类缓存的使用,需要的话可以参考官网写的很详细

Django同时还提供了底层缓存API,可以使用这个API以任意级别粒度在缓存中存储对象。这正是我所需要的,每次产生的新日志都不再直接写入数据库,而是先写入缓存中,待任务执行完成后一次写入数据库,这样将大大降低对数据库的消耗,且缓存大都使用内存来存储,读写效率极高

缓存配置

Django的底层缓存API使用非常简单,首先需要在配置文件中配置启用缓存,settings.py文件中添加如下代码

CACHES = {
    "default": {
            "BACKEND": "django_redis.cache.RedisCache",
            "LOCATION": "redis://127.0.0.1:6379",
            "OPTIONS": {
                "CLIENT_CLASS": "django_redis.client.DefaultClient",
            }
        }
}

这里使用了Memcached作为缓存服务,Memcached是一个完全基于内存的缓存服务器,是Django原生支持的最快、最高效的缓存类型,其他还支持的缓存类型有

  • 数据库缓存:django.core.cache.backends.db.DatabaseCache,LOCATION为表名
  • 文件系统缓存:django.core.cache.backends.filebased.FileBasedCache,LOCATION为文件路径
  • 本地内存缓存:django.core.cache.backends.locmem.LocMemCache,LOCATION被用于标识各个内存存储
  • 虚拟缓存:django.core.cache.backends.dummy.DummyCache,仅用于开发模式,只是实现缓存接口,并不做其他操作
  • 自定义的缓存后台,例如redis等

使用Memcached前需要先安装memcached服务,以及python连接memcached的包

# debian系统安装memcached服务
apt-get install memcached

# 安装python连接memcached的包python-memcached
pip install python-memcached

每个缓存后端都支持配置额外的参数,从而来控制缓存的行为,有效的参数如下:

TIMEOUT: 用于缓存的默认超时时间,以秒为单位,默认为300秒,当设置为None时表示永不过时,设置为0表示立刻过期不缓存

KEY_PREFIX: 缓存键前缀,如果有设置,则这个设置的值将自动添加到Django服务器使用的所有缓存键之前

VERSION: 通过Django服务器生成的缓存键的默认版本号,有点类似与Redis的db,以下例子能清晰展示VERSION的作用

>>> from django.core.cache import cache
>>>
>>> cache.set('site', 'test123.cn', version=37)
>>>
>>> cache.get('site')
>>>
>>> cache.get('site', version=37)
'test123.cn'
>>>

OPTIONS: 传递到缓存后端服务的参数,例如我要传递username、password等参数到后端的memcached服务,那么可以这样写

CACHES = {
    'default': {
        'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',
        'LOCATION': '127.0.0.1:11211',
        'OPTIONS': {
            'binary': True,
            'username': 'user',
            'password': 'pass',
            'behaviors': {
                'ketama': True,
            }
        }
    }
}

缓存访问
开启Django Cache配置后,就可以使用缓存服务了,基本用法如下

>>> from django.core.cache import cache

cache.set(key, value, timeout=DEFAULT_TIMEOUT, version=None)

其中key是一个字符串,value是一个认可picklable形式的python对象,timeoutversion参数都是可选的,timeout默认为CACHES配置中相应后端的timeout参数,version为对应的版本,参考上边关于VERSION的解释

>>> cache.set('site', 'test123.cn')
>>>
>>> cache.get('site')
'test123.cn'
>>>

cache.get(key, default=None, version=None)

新的参数default的意思是,当请求的key不存在时,则返回default设置的这个值,而不是默认不存在返回的`None

>>> cache.get('name')
>>>
>>> cache.get('name', 'has expired')
'has expired'

cache.add(key, value, timeout=DEFAULT_TIMEOUT, version=None)

cache.set类似,只是当add的key不存在时,则新建key,存在则不做任何操作

>>> cache.add('site', 'https://blog.test123.cn')
False
>>> cache.get('site')
'https://test123.cn'
>>>
>>> cache.get('name')
>>> cache.add('name', 'test')
True
>>> cache.get('name')
'test'

新建成功则会返回True,否则返回False

cache.get_or_set(key, default, timeout=DEFAULT_TIMEOUT, version=None)

需要2个参数,第一个为key,第二个为key不存在时设置的值。get_or_set意思是如果key存在,则返回key的值,如果不存在则给key设置一个值

>>> cache.get('name')
'test'
>>> cache.get_or_set('name', '咖啡吧博客')
'test'
>>>
>>> cache.get('path')
>>> cache.get_or_set('path', '/devops')
'/devops'
>>> cache.get('path')
'/devops'

cache.get_many(keys, version=None)

通过传入一个keys列表,以字典格式返回这些列表中key存在的缓存值

>>> cache.add('name', 'test')
True
>>> cache.set('site', 'https://test123.cn')
>>> cache.get_many(['site','name','path'])
{'site': 'https://test123.cn', 'name': 'test'}
cache.set_many(dict, timeout)

通过传入字典,批量设置缓存

>>> cache.set_many({'site':'test123.cn','name':'运维咖啡吧'})

cache.delete(key, version=None)

删除一个key

>>> cache.delete('site')

cache.delete_many(keys, version=None)

批量删除key

>>> cache.delete_many(['site','name'])

cache.clear()

清空缓存,需要注意的是这会删除缓存里的所有key,可能包含一些并不是你设置的key

>>> cache.clear()

cache.touch(key, timeout=DEFAULT_TIMEOUT, version=None)

更新key的过期时间为timeout设置的值,timeout是可选的,如果不写则默认为CACHES设置的TIMEOUT

>>> cache.touch('site', 3)
True

更新成功则返回True,否则返回False

cache.incr(key, delta=1, version=None)

incr递增一个已存在的int类型的key的值,默认情况下递增幅度为1,通过指定delta可以设置递增的幅度

>>> cache.set('num', 1)
>>> cache.incr('num')
2
>>> cache.incr('num', 10)
12

cache.decr(key, delta=1, version=None)

与incr递增类似,decr为递减

>>> cache.decr('num')
11
>>> cache.decr('num', 5)
6

cache.close()

如果缓存后端已经实现了close()方法,可以通过 cache.close() 关闭和缓存的连接

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐