背负青天而莫之夭阏者,而后乃今将图南。
百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 互联网 > 技术教程 > 正文

Django中使用Redis进行缓存

swdejp 2023-08-15 245 浏览 1 评论

应用程序的性能对于你的产品的成功与否显得至关重要。在用户想要网站在不到一秒1s的时间里响应的情况下,一个缓慢的应用程序就可以造成金钱上的损失。就算你没有在销售什么东西,更快的页面加载也会改善使用体验。

所有在服务器收到数据和作出响应之间发生的事情都会延长页面加载时间。照经验来说,在服务器省略越多的步骤,你的应用程序跑的就越快。在数据被处理后将其缓存并在下一次请求时直接拿出来是减轻服务器压力的一种方法。在这篇教程里,我们来研究一下拖慢你应用程序速度的因素,再演示怎样用Redis实现缓存来抵消那些因素的作用效果。

什么是Redis?

Redis是一个可以用来作为缓存引擎的基于内存的数据结构存储。既然它在内存中存储数据,那么速度一定很快。Redis不是唯一可以用来作为缓存的产品。Memcached便是另一款出名的基于内存的缓存系统,但很多人认为在大多数情况下Redis比Memcached更优秀。个人来说,我们喜欢它的设置简单以及还可以用于其他用途,比如说Redis Queue。

开始

我们创建了一个示例应用程序来向你介绍缓存的概念。我们的程序使用:

  • Django (v1.9.8

  • Django Debug Toolbar (v1.4

  • django-redis (v4.4.3

  • Redis (v3.2.0

安装这个程序

在你克隆仓库之前,先安装virtualenvwrapper,如果你还没有的话。这个工具让你安装你的项目需要的特定的Python依赖,并允许你定位你的app需要的版本和库。

接下来,把目录切换到你保存项目的地方再克隆示例程序仓库。完成以后,把目录切换进去,再用 mkvirtualenv 命令为示例程序创建一个新的虚拟环境:

注意:用 mkvirtualenv 命令创建一个虚拟环境也就同时把它激活了。

pip安装所有需要的Python依赖,再检查一下下面的标签:

通过构建数据库并向其中填入样本数据来结束示例程序的设置。别忘了创建一个超级用户,这样你才能登陆管理站点。跟随下面的示例代码再试试运行程序,确保它能正常工作。在浏览器里进入管理页确认一下数据是否正常加载。

当你的Django程序运行起来后,就去安装Redis。

安装Redis

按照文档里提供的步骤下载安装Redis。或者,你也可以用一个包管理器来安装Redis,比如说 apt-get或者homebrew,具体取决于你的操作系统。

在一个新的终端窗口中启动Redis服务:

接下来,在另一个终端窗口启动Redis命令行接口(CLI),测试一下是否连接到了Redis Server。 我们会用Redis CLI来检查添加到缓存中的键。

Redis提供了一个有着多种命令的API,开发者可以用来操作数据存储。Django使用 django-redis来在Redis里执行命令。

在一个文本编辑器里查看我们的示例程序,我们可以在 settings.py里看到Redis配置。我们在CACHES里定义了一个默认缓存,用内置的 django-redis 作为后端。Redis默认在6379端口运行,我们在设置里指出这个端口。最后要指出的是,django-redis附加了带有前缀和版本的键名来区分相似的键。所以我们把前缀定义为 "example"。

Django中使用Redis进行缓存

注意:虽然我们配置了缓存后端,但是还没有一个视图函数真正实现缓存。

程序性能

在这篇文章开头我们就曾提到,服务器处理一个请求所做的所有事情都会延长程序加载时间。运行业务逻辑和呈现模板的处理开销可能很大。网络潜在因素也会影响查询数据库的时间。每当一个客户端向服务器发送一个HTTP请求时,这些因素都会出现。当用户每秒发起多个请求时,由于服务器要处理所有请求,性能的影响将变得明显。

当我们实现缓存时,我们让服务器处理一次请求,然后将它存储在缓存中。当我们的应用程序接收到相同URL的请求时,服务器就直接从缓存中提取结果,而不是每次都重新处理它们。 通常,我们会设置缓存结果的存活时间,以便可以定期刷新数据,这是实现缓存的一个重要步骤,以避免提供过时的数据。

您应该考虑在以下情况存在时缓存请求的结果:

  • 呈现页面涉及到大量数据库查询和/或业务逻辑。

  • 页面经常被你的用户访问。

  • 每个用户的数据是相同的。

  • 数据不经常变化。

从测量性能开始

首先,通过衡量应用程序在收到请求后的响应速度来测试应用程序中每个页面的速度。

为了实现这一点,我们使用loadtest,一个HTTP负载生成器,用大量的请求来“轰炸”每个页面,再密切关注请求速率。点击上面的链接安装。安装好后,根据/cookbook/URL路径测试结果。

注意到我们每秒钟处理16个请求:

当我们看见代码在干什么的时候,我们就可以决定怎样作出改动来改善性能。该应用程序向一个数据库发出3个网络调用请求 /cookbook/,并且每次调用都需要时间打开一个连接并执行查询。在你的浏览器里访问/cookbook/URL并展开Django Debug工具栏选项卡以确认此行为。找到名为“SQL”的标签再看看查询的数目。

Django中使用Redis进行缓存

cookbook/services.py

cookbook/views.py

这个应用程序还会渲染一个有着潜在的开销巨大的逻辑的模板。

Django中使用Redis进行缓存

实现缓存

想象一下当用户访问我们的网站时我们的应用程序会发出的网络调用的总数。如果1000个用户调用获取cookbook的API,我们的程序就会进行3000次数据库查询,并且每次请求都会渲染一个新模板。这个数字会随着应用程序规模的增长而曾长。幸好,这个视图是用于缓存的不二之选。cookbook里的食谱很少变化。再说,既然app的中心作用是读取cookbook,那么获取食谱的API一定会被经常调用。

在下面的例子中,我们改变了视图函数以使其使用缓存。当函数工作时,它会检查视图键是否在缓存中。如果键存在的话,app就从缓存读取数据并返回。如果不在的话,Django就会查询数据库并将其和视图键存储在缓存中。函数第一次被调用时,Django会查询数据库并渲染模板,再向Redis发起网络调用将数据存进缓存。随后的函数调用将会完全绕过数据库和业务逻辑并直接查询Redis缓存。

Django中使用Redis进行缓存

注意我们向视图函数添加了一个装饰器 @cache_page,还添加了一个生存时间。再访问一下/cookbook/并检查Django Debug 工具栏。我们看到进行了3次数据库查询,并对缓存进行了3次调用,以便检查键,然后保存它。Django保存两个键(一个键用于标题,一个用于呈现的页面内容)。重新加载页面看看页面活动怎样变化的。第二次,数据库调用0次,缓存调用两次。我们的页面现在是缓存提供的!

当我们重新运行性能测试时,我们看到我们的程序加载更快了。

缓存提高了总负载量,我们现在每秒解析21个请求,比我们的基准多了5个。

用CLI检查Redis

这时候我们可以用Redis CLI看看Redis Server上存了些什么。在Redis命令行中,输入命令 keys *,这会返回满足任何模式的键。你应该会看到一个叫“example:1:views.decorators.cache.cache_page”的键。别忘了,“example”是我们的键前缀,“1”是版本,“views.decorators.cache.cache_page”是Django给键的名字。把键名复制下来输在get命令后面。你可以看到已渲染的HTML代码。

注意:在Redis CLI运行 flushall 命令来从数据存储里清除所有的键,然后你可以重新过一遍这个教程,不用等缓存过期了。

总结

处理HTTP请求的代价是昂贵的,并且会随着你的应用程序的数量增长而增加。有的情况下,实现缓存会极大地减少服务器的处理量。这篇教程涉及了在Django中用Redis实现缓存的一些基本点,略过了一些复杂的主题。在一个健壮的程序里实现缓存有很多陷阱。控制哪些数据被缓存和存活期有多长很困难。缓存失效是计算机科学中一件棘手的事情。保证私有数据只能被特定的用户访问是个安全问题并且需要在缓存时仔细处理。在示例程序中去玩转源码,并且在你继续用Django开发的时候,要常记着考虑性能。

英文原文:https://realpython.com/blog/python/caching-in-django-with-redis/

相关推荐

如何查看仓库(REPOSITORY)的具体版本了

我们通常从docker仓库里下载了PHP,不知道什么版本的。我们看一下库里有什么镜像[root@localhost~]#dockerimagels[root@localhost~]#doc...

程序员应知应会之Spring Data Jpa为什么不用写@Repository注解?

大家知道,在Springboot+SpringDataJpa的项目里,dao层只需要继承JpaRepository接口,就可以实现Mybatis中@Repository+mapper的效果,不需要...

Maven:mirror和repository的关系&区别

1.1结论1、repository(仓库)存放具体依赖jar包的地方,而mirror(镜像)是一个拦截器,可以拦截某个仓库将原始的仓库地址重定向到镜像指定的地址中去(主要是为了提高下载速度,例如从国...

终于弄懂了Spring@Component @Repository@Service的区别

专注于Java领域优质技术号,欢迎关注问题在spring集成的框架中,注解在类上的@Component,@Repository,@Service等注解能否被互换?或者说这些注解有什么区别?回答1引用s...

阿里技术专家详解DDD系列 第三讲 - Repository模式

作者|殷浩出品|阿里巴巴新零售淘系技术部写在前面:这篇文章和《阿里技术专家详解DDD系列第二弹-应用架构》隔了比较久,一方面是工作比较忙,另一方面是在讲Repository之前其实应该先讲Ent...

领域实体是否可以访问资源库Repository?

领域实体(Domainentities)通常指的是在软件开发领域中用于表示业务逻辑和业务规则的对象。这些对象通常封装了与特定领域相关的数据和行为。领域实体是否可以访问资源库(Repository),...

GitHub入门创建仓库和管理仓库(Repository)

一个Git库(仓库)对应一个开源项目,通过Git管理Git库。创建仓库在GitHub主页点击“Startaproject”,然后输入:Repositoryname(仓库名称,一般是项目名称)、D...

单细胞分析:marker鉴定(11)

导读前面我们已经确定了我们想要的簇,我们可以继续进行标记识别,这将使我们能够验证某些簇的身份并帮助推测任何未知簇的身份。1.学习目标学会确定单个簇的marker学会在聚类和marker识别间进行迭代...

FreeMarker介绍

1.1FreeMarker简介lFreeMarker是一个模板引擎,一个基于模板生成文本输出的通用工具,使用纯Java编写lFreeMarker被设计用来生成HTMLWeb页面,特别是基于M...

分手的时候,教你一招怎么将自己和前男/女友从照片里面分割出去

分手的时候,很多人看着以前的亲密照片,最想做的是啥?对,没错,就是剪照片或者撕照片。但是有的时候,那个照片你又很喜欢,不舍得删除电子照片怎么办?今天教你一招,怎么将ta分割出去。这个办法很简单,就是使...

使用 Plotly 绘图的太阳系 3D 模型

太阳系太阳系是一个受太阳引力约束在一起的恒星系统,包括太阳以及直接或间接围绕太阳运动的天体。轨道环绕太阳的天体被分为三类:行星、矮行星、和太阳系小天体。行星是环绕太阳且质量够大的天体。这类天体:1、有...

261.C# ScottPlot 基本入门

摘要ScottPlot是一个功能强大的C#绘图库,特别适用于WinForm开发。它提供了丰富的图表类型和定制化选项,使开发者能够轻松地在应用程序中绘制高质量的图表和数据可视化。正文数据可视化:Scot...

「Plotly快速入门」用Plotly绘制了几张精湛的图表,美翻了

作者:俊欣来源:关于数据分析与可视化说到Python当中的可视化模块,相信大家用的比较多的还是matplotlib、seaborn等模块,今天小编来尝试用Plotly模块为大家绘制可视化图表,和前两者...

SAM + YOLO = 自动抠图

在计算机视觉领域,对象检测和实例分割是使机器能够理解视觉数据并与之交互的关键任务。准确识别和隔离图像中的物体的能力具有许多实际应用,从自动驾驶车辆到医学成像。在这篇博文中,我们将探索如何在Robo...

Matplotlib画图如此简单

jupyter入门之Matplotlib一.Matplotlib基础知识Matplotlib中的基本图表包括的元素x轴和y轴axis水平和垂直的轴线轴标签axisLabel水平和垂直的轴标签...

已有1位网友发表了看法:

  • swdejp

    swdejp  评论于 [2022-03-07 21:23:04]  回复

    django redis

取消回复欢迎 发表评论: