Django缓存机制

 缓存

是一类可以更快的读取数据的介质统称,也指其它可以加快数据读取的存储方式。一般用来存储临时数据,常用介质的是读取速度很快的内存。一般来说从数据库多次把所需要的数据提取出来,要比从内存或者硬盘等一次读出来付出的成本大很多。对于中大型网站而言,使用缓存减少对数据库的访问次数是提升网站性能的关键之一。

Redis

它是基于内存的缓存型数据库,同时支持数据序列化相比而言更加安全。Redis 的工作流程总结如下:先检查客户端的请求数据是否在 Redis 中,如有,直接把请求数据返回,不再对数据库进行任何操作;如果请求的数据不在 Redis 中,就去查数据库,把从数据库中获取的数据返回给客户端,同时把数据缓存一份到 Redis 中;每次更新数据库的同时更新 Redis 中的数据,保证与数据库的一致性。 

Django

提供了一个稳定的缓存系统让你缓存动态页面的结果,这样在接下来有相同的请求就可以直接使用缓存中的数据,避免不必要的重复计算。 另外Django还提供了不同粒度数据的缓存,例如: 你可以缓存整个页面,也可以缓存某个部分,甚至缓存整个网站。

Memcache与Redis的区别都有哪些?
1)、存储方式
Memecache把数据全部存在内存之中,断电后会挂掉,数据不能超过内存大小。
Redis有部份存在硬盘上,这样能保证数据的持久性。
2)、数据支持类型
Memcache对数据类型支持相对简单。
Redis有复杂的数据类型。
3)、value大小
redis最大可以达到1GB,而memcache只有1MB

如何进行缓存 

缓存粒度分类

Per-site cache 把整个网站都缓存了,只需要在项目中设置加入缓存中间键的配置,系统便会自动对整个网站进行缓存

  • Per-view cache 缓存某个视图
  • Template fragment caching 模板的片段,比如Django模板继承base.html,通常是不变的导航栏
  • Low-level cache API 低级别缓存API,比如缓存某个函数的结果,或者某个API接口

Django 提供了六种常用的缓存机制

  • 开发调试缓存
  • 内存缓存
  • 文件缓存
  • 数据库缓存
  • Memcache缓存(使用python-memcached模块)
  • Memcache缓存(使用pylibmc模块)

经常使用的有文件缓存和Mencache缓存,

内存缓冲Memcache设置

Memcached是迄今为止可用于Django的最快,最有效的缓存类型,Memcached是完全基于内存的缓存框架。配置地址和端口,不一定是要在本机,也可以是其它网段的服务器或集群,在本机的话,也可以使用unix Socket,也可以使用多态服务器,不同端口缓存。对于Django项目缓存的数据,我们取出来或存进去操作,可以不需要直接操作底层的缓存数据,比如使用原生的Redis或Memcached命令,只需要使用Django提供的缓存API即可。就像我们使用Django ORM一样,无需关注底层数据库是MySQL, PostgreSQL或SQLite,ORM语句都一样。

  

  

  

配置都需要如下,根据方法不同只有引擎不同

1.2.1 开发调试(此模式为开发调试使用,实际上不执行任何操作)

'BACKEND': 'django.core.cache.backends.dummy.DummyCache',  # 缓存后台使用的引擎
1.2.2 内存缓存(将缓存内容保存至内存区域中)
'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',  # 指定缓存使用的引擎
1.2.3 文件缓存(把缓存数据存储在文件中)
 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', #指定缓存使用的引擎
1.2.4 数据库缓存(把缓存数据存储在数据库中)
  'BACKEND': 'django.core.cache.backends.db.DatabaseCache',  # 指定缓存使用的引擎
1.2.5 Memcache缓存(使用python-memcached模块连接memcache)
 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', # 指定缓存使用的引擎
1.2.6 Memcache缓存(使用pylibmc模块连接memcache)
 'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache',  # 指定缓存使用的引擎
CACHES = {
                'default': {
                 'BACKEND': 'django.core.cache.backends.filebased.FileBasedCache', #指定缓存使用的引擎
                 'LOCATION': 'D:学习工具作业',        #指定缓存的路径
                 'TIMEOUT':300,              #缓存超时时间(默认为300秒,None表示永不过期)
                 'OPTIONS':{
                  'MAX_ENTRIES': 300,            # 最大缓存记录的数量(默认300)
                  'CULL_FREQUENCY': 3,           # 缓存到达最大个数之后,剔除缓存个数的比例,即:1/CULL_FREQUENCY(默认3)
                 }
                }
               }
1,全站缓存   在中间件里面配置,

-配置两个中间件:
    'django.middleware.cache.UpdateCacheMiddleware' #重写了response方法
   ...
   'django.middleware.cache.FetchFromCacheMiddleware'#重写了request方法
   
-配置缓存时间
   CACHE_MIDDLEWARE_SECONDS=10

2,页面缓存   导入模块加装饰器

from django.views.decorators.cache import cache_page
@cache_page(5)
3,局部缓存

 {%load cache%}

{%cache 10#时间 ‘time'#唯一的key区分其他%}

{{ctime}}

{%endcache%}

在Django中,当用户请求到达视图后,视图会先从数据库提取数据放到模板中进行动态渲染,渲染后的结果就是用户看到的网页。如果用户每次请求都从数据库提取数据并渲染,将极大降低性能,不仅服务器压力大,而且客户端也无法即时获得响应。如果能将渲染后的结果放到速度更快的缓存中,每次有请求过来,先检查缓存中是否有对应的资源,如果有,直接从缓存中取出来返回响应,节省取数据和渲染的时间,不仅能大大提高系统性能,还能提高用户体验。 

我们来看一个实际的博客例子。每次当我们访问首页时,下面视图都会从数据库中提取文章列表,并渲染的模板里去。大多数情况下,我们的博客不会更新得那么频繁,所以文章列表是不变的。这样用户在一定时间内多次访问首页时都从数据库重新读取同样的数据是一种很大的浪费。

from django.shortcuts import render
  
def index(request):
  # 读取数据库等并渲染到网页
  article_list = Article.objects.all()
  return render(request, 'index.html', {'article_list': article_list})

 使用缓存Cache就可以帮我们解决这个问题。当用户首次访问博客首页时,我们从数据库中提取文章列表,并将其存储到缓存里(常用的是内存,这取决于你的设置)。当用户在单位时间内再次访问首页时, Django先检查缓存是否过期(本例是15分钟), 再检查缓存里文章列表资源是否存在,如果存在,直接从缓存中读取数据, 并渲染模板。

from django.shortcuts import render
from django.views.decorators.cache import cache_page
  
  
@cache_page(60 * 15) # 秒数,这里指缓存 15 分钟
def index(request):
  article_list = Article.objects.all()
  return render(request, 'index.html', {'article_list': article_list})

缓存主要适用于对页面实时性要求不高的页面。存放在缓存的数据,通常是频繁访问的,而不会经常修改的数据。我们来举几个应用例子:

  • 博客文章。假设用户一天更新一篇文章,那么可以为博客设置1天的缓存,一天后会刷新。
  • 购物网站。商品的描述信息几乎不会变化,而商品的购买数量需要根据用户情况实时更新。我们可以只选择缓存商品描述信息。
  • 缓存网页片段。比如缓存网页导航菜单和脚部(Footer)。

Django缓存设置

缓存系统需要一些少量的设定工作。 也就是说,你必须告诉它缓存的数据应该放在哪里,在数据库中,在文件系统,或直接在内存中。 这影响高速缓存的性能,有些类型的缓存比其它类型快。

Django中提供了多种缓存方式,如果要使用缓存,需要先在settings.py中进行配置,然后应用。根据缓存介质的不同,你需要设置不同的缓存后台Backend。

Memcached缓存

Memcached是基于内存的缓存,Django原生支持的最快最有效的缓存系统。对于大多数场景,我们推荐使用Memcached,数据缓存在服务器端。使用前需要通过pip安装memcached的插件python-memcached和pylibmc,可以同时支持多个服务器上面的memcached。

# localhost
CACHES = {
  'default': {
    'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
    'LOCATION': '127.0.0.1:11211',
  }
}
  
# unix soket
CACHES = {
  'default': {
    'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
    'LOCATION': 'unix:/tmp/memcached.sock',
  }
} 
  
CACHES = {
  'default': {
    'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
    'LOCATION': [
      '172.19.26.240:11211',
      '172.19.26.242:11211',
    ]
    # 我们也可以给缓存机器加权重,权重高的承担更多的请求,如下
    'LOCATION': [
      ('172.19.26.240:11211',5),
      ('172.19.26.242:11211',1),
    ]
  }
 }

数据库缓存 


CACHES = {
  'default': {
    'BACKEND': 'django.core.cache.backends.db.DatabaseCache',
    'LOCATION': 'my_cache_table',
  }

文件系统缓存

CACHES = {
  'default': {
    'BACKEND': 'django.core.cache.backends.filebased.FilebasedCache',
    'LOCATION': '/var/tmp/django_cache',#这个是文件夹的路径
    #'LOCATION': 'c:foobar',#windows下的示例
  }
}

本地内存缓存

CACHES = {
  'default': {
    'BACKEND': 'django.core.cache.backends.locmem.LocMemCache',
    'LOCATION': 'unique-snowflake'
  }
}

当你做好Cache的设置后,在代码中你可以有三种方式使用Cache。

  • 在视图View中使用
  • 在路由URLConf中使用
  • 在模板中使用

在视图View中使用cache

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

在路由URLConf中使用cache

不用修改负责逻辑部分的view了。

from django.views.decorators.cache import cache_page
  
urlpatterns = [
  path('foo/<int:code>/', cache_page(60 * 15)(my_view)),
]

在模板中使用cache

{% load cache %}
{% cache 500 sidebar request.user.username %}
  .. sidebar for logged in user ..
{% endcache %}

Django中使用Cache的高级技巧

使用cache_control

通常用户将会面对两种缓存: 他或她自己的浏览器缓存(私有缓存)以及他或她的提供者缓存(公共缓存)。 公共缓存由多个用户使用,而受其它人的控制。 这就产生了你不想遇到的敏感数据的问题,比如说你的银行账号被存储在公众缓存中。 因此,Web 应用程序需要以某种方式告诉缓存那些数据是私有的,哪些是公共的。

解决方案是标示出某个页面缓存应当是私有的。 要在 Django 中完成此项工作,可使用 cache_control 视图修饰器:

from django.views.decorators.cache import cache_control
  
@cache_control(private=True)
def my_view(request):
# ...

该修饰器负责在后台发送相应的 HTTP 头部。

还有一些其他方法可以控制缓存参数。 例如, HTTP 允许应用程序执行如下操作:

  1. 定义页面可以被缓存的最大时间。
  2. 指定某个缓存是否总是检查较新版本,仅当无更新时才传递所缓存内容。

在 Django 中,可使用 cache_control 视图修饰器指定这些缓存参数。 在下例中, cache_control 告诉缓存对每次访问都重新验证缓存并在最长 3600 秒内保存所缓存版本。

from django.views.decorators.cache import cache_control
  
  
@cache_control(must_revalidate=True, max_age=3600)
def my_view(request):
# ...

在 cache_control() 中,任何合法的Cache-Control HTTP 指令都是有效的。下面是完整列表:

  • public=True
  • private=True
  • no_cache=True
  • no_transform=True
  • must_revalidate=True
  • proxy_revalidate=True
  • max_age=num_seconds
  • s_maxage=num_seconds

使用vary_on_headers

缺省情况下,Django 的缓存系统使用所请求的路径(如blog/article/1)来创建其缓存键。这意味着不同用户请求同样路径都会得到同样的缓存版本,不考虑客户端user-agent, cookie和语言配置的不同, 除非你使用Vary头部通知缓存机制需要考虑请求头里的cookie和语言的不同。

要在 Django 完成这项工作,可使用便利的 vary_on_headers 视图装饰器。例如下面代码告诉Django读取缓存数据时需要同时考虑User-Agent和cookie的不同。

from django.views.decorators.vary import vary_on_headers
  
@vary_on_headers('User-Agent', 'cookie')
def my_view(request):
  ...

使用never_cache禁用缓存

如果你想用头部完全禁掉缓存, 你可以使用django.views.decorators.cache.never_cache装饰器。如果你不在视图中使用缓存,服务器端是肯定不会缓存的,然而用户的客户端如浏览器还是会缓存一些数据,这时你可以使用never_cache禁用掉客户端的缓存。

from django.views.decorators.cache import never_cache
  
@never_cache
def myview(request):
# ...

文章载自

第十五章: 缓存机制

 www.kaotop.com

python缓存技术_Python学习教程(技术分享):Django项目缓存优化_weixin_39645249的博客-CSDN博客

django缓存优化(二) | 缓存

中间件几种方法,django 缓存粒度,配置方法,redis - 走看看

Django中的缓存机制及其实现方法 

 memcached 详解_冯巩2.0的博客-CSDN博客_memcached

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值