2天时间,聊今年最热的 Agent、上下文工程、AI 产品创新等话题。2025 年最后一场~ 了解详情
写点什么

使用 Redis 查询缓存

  • 2019-10-24
  • 本文字数:2818 字

    阅读完需:约 9 分钟

使用Redis查询缓存

当我开始搭建网站时,我并没有太注重性能。一旦你掌握一些基础知识,比如 HTML 和 CSS,或者你在后端使用的任何编程语言,性能就成了你担心的奢侈品。初学者的目标是建一个网站,能够从一个页面跳转到另一个页面,并确保它在服务器上看起来运行地很好。缓存和性能是我们后面要解决的问题。


有很多很好的理由来研究缓存解决方案。从 SEO(搜索引擎优化)的角度来看,谷歌会惩罚加载缓慢的网站。如果你的网站加载需要很长时间,网站排名可能会受到影响,这当然会对收入产生严重的影响。Google 的 John Mueller 说,页面加载时间超过两秒钟会“影响爬取”你的网站数据,他会寻找加载时间少于 2-3 秒的网站。另一个因素是加载缓慢的网站可用性影响。当我开始编码时,完全加载一个页面大约需要 8 秒钟是可接受的。只有花了更长的时间,你才会担心人们会放弃这个页面。如今,这个时间大约是两秒钟,可能会更少,具体取决于你所在的行业。


底线:你的网站越快,排名越好,访问者留下和互动的次数就越多。但是,直到我的客户打电话说他们的新网站“太慢”时,这个问题才引起我的注意。理性地分析,它上面有一些较大的图像,他们正在使用一个糟糕的托管平台。这也回到了 10 美元托管意味着你的网站运行在共享服务器上的一天。他们对服务器优化的想法是安装最新版本的 CPanel(yikes)。经过一番挖掘,我构建了一个基本的页面缓存系统,它运行得很好。客户很高兴,我开始学习一种新的技能,一切都很好。但很快我意识到,虽然页面级缓存是一个很好的工具,但它只是一个工具。

当页面缓存不足时

页面缓存的工作方式如下:一个请求传入,服务器处理它,然后存储结果 HTML。为了说明本篇博客的场景,让我们使用 Redis 的一个例子。下次有人请求我们的页面时,它将首先检查缓存。如果页面在缓存中存在,系统将使用该页面,而不是在服务器级别处理请求。


这种场景适用于不会改变太多的页面,例如条款和条件或隐私政策。这些页面的流量不同于主应用程序,后者可能具有基于用户的动态数据。


假设我们有一个充当用户目录并允许基于某种活动进行过滤的应用程序。用户可以查看人员列表并查看他们的电子邮件地址和电话号码。我们的应用程序使用 SQL 数据库,因此要获取该数据,我们需要一个简单的选择查询:


SELECT username,email, phone_number FROM users WHERE activity='baseball';
复制代码


在我们的应用程序中,假设活动是用户在注册时设置的列表。因此,人们可以看到的活动类型因用户而异。我们将活动列表存储在另一个表中,并且也需要此页面上的信息。


SELECT name, id FROMactivity_list WHERE user_id=1;
复制代码


在这种情况下,我们有一个需要针对当前用户运行的查询。该用户看到的数据是整个列表的一个子集,对于他们来说是唯一的。。考虑到这一点,我们无法缓存页面,因此我们需要缓存每个单独的查询。

查询缓存,而不是页面缓存

现在我们需要考虑何时缓存查询以及如何缓存。一个简单的解决方案是使用 Redis Hashes 存储我们的结果集。我们可以将数据存储为 JSON 编码字符串,当我们准备好之后,只需将其取出并在我们的代码库中使用它。


那么缓存是什么样子的呢?下面是一些伪代码:


> HGETuser-activity-list cacheif the result isnot nil return the result set else go to step 3run the query andsave the DB result set to a variableif the DB resultsize is > 0transform theresult set data to a JSON string> HSETuser-activity-list cache JSON string result setelse result set<= 0 throw error
复制代码


关于上面的伪代码,我应该指出,当然我们忽略了这实际上是会话存储模式的事实。在现实世界中,你不会只想在 Redis 中永久缓存这些查询,只有在用户登录并在你的站点上活动时才创建和存储这些查询。我在 Redis 中创建了这个通用的用户活动列表键,仅作为一个示例来演示理论并激发你如何在自己的代码中执行此操作的想法。


除此之外,我们的键名也不是最好的。“用户活动列表”的名称也同样仅适用于这个非常通用和狭窄的示例。对于实际的应用程序,你可能希望以一种更可预测的方式命名你的键名。如果我真的这么做的话,这个键就会在某个地方有用户名,这都是用户会话的一部分,这样就可以很容易地检索和使用。


继续,我们应该解决几个问题。首先,我们获取了用户活动列表,但是在我们运行此查询一次后,我们应该使查询过期,这样我们就不会冒险向用户显示一些相当陈旧的数据。我们可以通过几种不同的方式来解决这个问题。

写入时过期

假设此活动列表是用户自己更新的内容。她会去设置页面,摆弄一些东西,并保存更改。她每周只能这样做一次或每月一次。在这种情况下,我们可以保留缓存,直到用户更改某些内容:


1.用户添加“sportsball”列表并保存


2.为了响应用户的保存,我们取消了用户活动列表的链接


你可以按照自己喜欢的方式完成第一部分和第二部分。对于这个系统,我假装我们有办法注册/推送事件。那部分并不重要,但重要的是我们的系统每次更新时都会删除缓存。我们不需要担心重新缓存数据,因为这是原始函数的工作。

定时过期

在写入时过期可能并不适用于每个场景。在有些情况下,我们只希望缓存一定时间的查询。对于这些,我们可以使用 Redis 来过期我们的键。


让我们拿出第一个缓存解决方案,看看它里面的 Redis 是什么样子的:


1.> HGET 获取用户活动列表缓存


2.如果结果不是 nil 则返回缓存值,否则转到步骤 3


3.运行查询并将 DB 结果集保存到变量


4.如果 DB 结果大小> 0


5.将结果集数据转换为 JSON 字符串


HSET 用户活动列表缓存 JSON 字符串结果


EXPIRE 用户活动列表 100


这里的诀窍是第五步。设置键后,我们使用 Redis 设置该键的过期时间(以秒为单位)。Redis 将为我们删除 key,因此我们不必担心在我们的代码中管理它。

结论

在页面级缓存不起作用或效率低下的情况下,缓存数据库查询是一个很好的选择。我们可以使用 Redis 设置并获取带有保存查询值的哈希值,并返回这些值而不是命中数据库。这将极大地加速我们的网站访问速度。想一想:从数据库访问信息并将信息返回给用户的标准时间是 100 毫秒,而 Redis 的平均时间只有 2 毫秒。这是一个巨大的性能提升。


在我们虚构的应用程序中,如果用户每小时点击这个活动页面 1000 次,而我们每次都必须访问数据库,那就会加起来(这只用于一个查询)。想象一下,如果这个页面有 2-5 个查询?如果这些查询需要多个表的复杂联接,该怎么办?一个页面上的三个同步查询很容易花费 300 毫秒以上才能从数据库返回数据。在一个我们只有 2-3 秒钟来吸引用户注意力的世界中,为什么要把自己置于不利地位?


现在,假设我们可以从缓存 90% 的时间中检索数据。


在 Redis 中缓存查询可以使单个页面的访问时间从 300 毫秒缩小为 6 毫秒。访问整个网站,抓取数据需要花费的时间将从数分钟减少到仅几秒钟。这是一个性能提升,应该会让极大提升客户体验。


本文转载自公众号中间件小哥(ID:huawei_kevin)。


原文链接:


https://mp.weixin.qq.com/s/HSOh1tA3rI5oS_iUOwGQ7g


2019-10-24 16:033502

评论

发布
暂无评论
发现更多内容

谈兼职创业

Ryan Zheng

一文搞定Diff算法

执鸢者

Vue 大前端 Diff

《青春有你3》的子弹时间舞台,凝筑了自由视角技术进化史

脑极体

Spark详细剖析

五分钟学大数据

大数据 spark 28天写作 3月日更

2021十大区块链领域即将起飞

CECBC

区块链 投资

央行数字人民币“可控匿名”会侵犯隐私吗?最新解读来了

CECBC

数字货币

产品训练营第八周作业——用户路径地图

innovator琳

用户研究 用户地图 用户数据 用户模型

2.3 Go语言从入门到精通:数据类型

xcbeyond

3月日更 Go 语言

产品训练营第八章作业

Arnold

IO 模型

无心

Netty

架构师训练营 4 期 第12周

引花眠

架构师训练营 4 期

银行业只是开始,60个可以被区块链改变的行业

CECBC

数字技术

hive数据倾斜解决办法

五分钟学大数据

大数据 hive 28天写作 3月日更

传统IT部门为什么越来越不受欢迎?

boshi

数字化转型 IT职场 七日更

科技强国的使命召唤中,百度AI埋下三根未来“引线”

脑极体

从Nacos客户端视角来分析配置中心原理

麦洛

nacos SpringCloud Alibaba 动态配置

控制台的安装与使用 | 联盟链开发(二)

李大狗

联盟链 FISCO BCOS 狗哥

OpenCV 写图像也有讲究,取经之路第 5 天

梦想橡皮擦

28天写作 3月日更

产品0期-第九周

Jxin

用户故事拆分速查手册(译)

Bruce Talk

敏捷 译文 Agile User Story

找到适合自己的睡眠方案

石云升

生活方式 28天写作 睡眠 3月日更

线上问题的一点反思

风翱

复盘 3月日更 线上问题

大数据中流量分析常见分类

大数据技术指南

大数据 28天写作 3月日更

Java8中的 Stream 那么彪悍,你知道它的原理是什么吗?

Java小咖秀

Java 面试 stream java8 开发

Vue3源码 | createApp都干了什么?

梁龙先森

源码分析 大前端 Vue3

数据仓库设计

大数据技术指南

大数据 28天写作 3月日更

Go Channel源码分析

非晓为骁

源码分析 channel Go 语言

探索 Snabbdom 模块系统原理

Geek_z9ygea

JavaScript Vue Web Vue 3 Snabbdom

工作多年后我更明白了UT的重要性

好好学习,天天向上

Docker 教程(三):Docker 命令

看山

Docker

为何数字人民币要采用“小额匿名、大额可溯”的设计?

CECBC

数字货币

使用Redis查询缓存_文化 & 方法_Joe Cianflone_InfoQ精选文章