按照《大型网站技术架构》中所说,网站性能优化的第一定律:优先考虑缓存优化性能.今天简单探讨下django的缓存实现。

缓存一些东西是为了保存那些需要很多计算资源的结果,这样的话就不必在下次重复消耗计算资源。 下面是一些伪代码,用来解释缓存怎样在动态生成的网页中工作的:

1
2
3
4
5
6
7
iven 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

Django中的缓存类型

  • 1、内存缓存
  • 2、数据库缓存
  • 3、文件缓存

Django如何设置缓存

缓存系统需要一些设置才能使用。 也就是说,你必须告诉他你要把数据缓存在哪里- 是数据库中,文件系统或者直接在内存中。 这个决定很重要,因为它会影响你的缓存性能,缓存配置是通过setting 文件的CACHES 配置来实现的。

缓存参数
  • TIMEOUT: 用于缓存的默认超时(以秒为单位)。此参数默认为300秒(5分钟)。

  • OPTIONS: 应传递给缓存后端的任何选项。(包括以下)

  • MAX_ENTRIES:删除旧值之前缓存中允许的最大条目数。此参数默认为300。
  • CULL_FREQUENCY:MAX_ENTRIES达到时剔除的条目部分。实际比率是 ,设置为在达到时剔除一半数目。
  • EY_PREFIX:一个字符串,将自动包含(默认情况下预先添加)到Django服务器使用的所有缓存键。
  • VERSION:Django服务器生成的缓存键的默认版本号。
  • KEY_FUNCTION 包含函数的虚线路径的字符串,用于定义如何将前缀,版本和密钥组合为最终缓存键。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ###例子
    CACHES = {
    'default': {
    'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache',
    'LOCATION': '/var/tmp/django_cache',
    'TIMEOUT': 60,
    'OPTIONS': {
    'MAX_ENTRIES': 1000
    }
    }
    }
内存缓存(Memcached)

Memcached是Django本身支持的最快,最有效的缓存类型,它 是一个完全基于内存的缓存服务器,最初是为了处理LiveJournal.com的高负载而开发的,后来由Danga Interactive开源。Facebook和Wikipedia等网站使用它来减少数据库访问并显着提高网站性能。

Memcached作为守护进程运行,并分配了指定数量的RAM。它所做的就是提供一个快速接口,用于在缓存中添加,检索和删除数据。所有数据都直接存储在内存中,因此不会产生数据库或文件系统使用的开销。

安装Memcached本身后,您需要安装Memcached绑定。有几个Python Memcached绑定可用; 最常见的两个是python-memcached和pylibmc。

在Django中使用Memcached:

  • 设置BACKEND为 django.core.cache.backends.memcached.MemcachedCache或 django.core.cache.backends.memcached.PyLibMCCache(取决于您选择的memcached绑定)
  • 设置LOCATION为ip:port值,其中ip是Memcached守护程序的IP地址,port是运行Memcached的端口,或者是unix:path值,其中 path是Memcached Unix套接字文件的路径。

Memcached使用python-memcached绑定在localhost(127.0.0.1)端口11211上运行:

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

Memcached可通过/tmp/memcached.sock使用python-memcached绑定的本地Unix套接字文件:

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

用pylibmc绑定时,请不要包含unix:/前缀:

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

数据库缓存

Django可以将其缓存的数据存储在您的数据库中。如果你有一个快速,索引良好的数据库服务器,这种方法效果最好。

要将数据库表用作缓存后端:

  • 设置BACKEND为 django.core.cache.backends.db.DatabaseCache
  • 设置LOCATION为tablename,数据库表的名称,注意这个表应该是还没有新增的。

缓存表的名称为my_cache_table:

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

创建缓存表,在使用数据库缓存之前,必须使用以下命令创建缓存表:

1
python manage.py createcachetable
多个数据库

如果对多个数据库使用数据库缓存,则还需要为数据库缓存表设置路由指令。出于路由的目的,数据库缓存表CacheEntry在名为的应用程序中显示为名为的模型 django_cache。此模型不会出现在模型缓存中,但模型详细信息可用于路由目的。

例如,以下路由器将指向所有高速缓存读取操作cache_replica,并将所有写入操作指向 cache_primary。缓存表将仅同步到 cache_primary:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class CacheRouter:
"""A router to control all database cache operations"""

def db_for_read(self, model, **hints):
"All cache read operations go to the replica"
if model._meta.app_label == 'django_cache':
return 'cache_replica'
return None

def db_for_write(self, model, **hints):
"All cache write operations go to primary"
if model._meta.app_label == 'django_cache':
return 'cache_primary'
return None

def allow_migrate(self, db, app_label, model_name=None, **hints):
"Only install the cache model on primary"
if app_label == 'django_cache':
return db == 'cache_primary'
return None

如果未指定数据库缓存模型的路由方向,则缓存后端将使用该default数据库。当然,如果不使用数据库缓存后端,则无需担心为数据库缓存模型提供路由指令。

文件系统缓存

基于文件的后端将每个缓存值序列化并存储为单独的文件。要使用此后端设置BACKEND来 “django.core.cache.backends.filebased.FileBasedCache”和 LOCATION到合适的目录。例如,要存储缓存数据/var/tmp/django_cache,请使用以下设置:

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

如果您使用的是Windows,请将驱动器号放在路径的开头,如下所示:

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

缓存整个站点

可以在settings配置文件添加如下:

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

views视图缓存

1
2
3
4
5
from django.views.decorators.cache import cache_page

@cache_page(60 * 15)
def my_view(request):
...

注意:cache_page:缓存时间以秒为单位

访问缓存

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

基本用法

语法:

  • 新增缓存:

    1
    2
    set(key, value, timeout)
    get(key) --- 当存在key不会再新增
  • 获取缓存:

    1
    2
    get(key)---获取单个值
    get_many(['key1', 'key2', 'key3'])---获取多个值
  • 删除缓存

    1
    cache.delete('a')
  • 清空缓存

    1
    cache.clear()

还可以分别使用incr()或decr()方法增加或减少已存在的密钥 。默认情况下,现有缓存值将递增或递减1.可以通过为递增/递减调用提供参数来指定其他递增/递减值。如果您尝试递增或递减不存在的缓存键,将引发ValueError:

1
2
3
4
5
6
7
8
9
>>> cache.set('num', 1)
>>> cache.incr('num')
2
>>> cache.incr('num', 10)
12
>>> cache.decr('num')
11
>>> cache.decr('num', 5)
6

要是还有疑问,具体可参考:https://docs.djangoproject.com/zh-hans/2.0/topics/cache/

Comments

2018-07-29