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:033508

评论

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

当你在跑步时在想什麽? 这个是村上春树的,当你在骑摩托车时在想什麽? 这个是波西格的

叶小鍵

拍乐云基于AV1的实时视频系统技术实践 | 2021 LiveVideoStackCon 演讲回顾

拍乐云Pano

音视频 WebRTC RTC

WeTest六周年 | 匠心不改 初心不变

WeTest

OCR的工作原理和应用场景

澳鹏Appen

人工智能 机器学习 OCR 训练数据 文本识别

漏洞深入分析-2021

网络安全学海

网络安全 信息安全 渗透测试 WEB安全 安全漏洞

如何快速搞定第三方登录且易扩展?

Tom弹架构

Java 架构 设计模式

极客 - 大数据 - 作业 Flink

西伯利亚鼯鼠

【Redis技术专题】分析一下Redission实现分布式锁的点点滴滴

码界西柚

redis redission redisson 分布式锁 11月日更

MRS HetuEgine的数据虚拟化实践

华为云开发者联盟

大数据 数据湖 云原生 华为云 数据虚拟化

APP上跑小程序,一箭双雕

Speedoooo

ios开发 APP开发 Andriod开发

我凭借这份pdf,最终拿到了阿里,腾讯,京东等八家大厂offer

Java 编程 程序员 面试

惊艳11月!日更挑战你准备好了么!?

InfoQ写作社区官方

11月日更 热门活动

不懂乐理和五线谱也能快速入门电子音乐制作!用FL Studio 搞音乐创作有时候就是这么简单!

懒得勤快

03 K8S之网络互联通信

穿过生命散发芬芳

k8s 11月日更

恒源云(GpuShare)_【功能更新】镜像市场上线

恒源云

深度学习

LCN基本原理

平凡人生

增量编译:让小程序包编译速度提升11倍!

Speedoooo

容器 ios开发 APP开发 Andriod开发

闻香识代码,什么是衡量代码质量的终极标准?

Zilliz

Java 代码质量 JavaScrip

30K成功入职京东:拿到京东offer经验分享「面试经历+面试真题」

Java redis spring 程序员 JVM

毕业总结

面向对象的猫

毕业总结

lims实验室信息监控管理系统解决方案

低代码小观

企业管理 管理系统 LIMS实验室信息管理系统 LIMS系统 信息管理系统

拥有3000多万用户的录屏软件,到底强在哪儿?

淋雨

Camtasia

网易智企斩获“2021全球新经济卓越成就奖”两项大奖

网易云信

大数据 云通信 通信云

云小课|三大灵魂拷问GaussDB(DWS)数据落盘安全问题

华为云开发者联盟

安全 云小课 GaussDB(DWS) 数据仓库服务 数据落盘安全

公司刚来的阿里p8,看完我构建的springboot框架,甩给我一份文档

Java 编程 程序员 Spring Boot

APP与小程序,相爱相杀

Speedoooo

容器 ios开发 APP开发 Andriod开发

pygame 中的图形绘制函数、帧速率和文字相关知识,简单的的不得了

梦想橡皮擦

11月日更

实现连续测试,要做的事情【译】

FunTester

敏捷 自动化 持续集成 FunTester 连续测试

架构实战营 - 毕业总结

燕燕 yen yen

架构训练营

Android技术分享| Android WebRTC 开启H264软件编解码教程

anyRTC开发者

android 音视频 WebRTC ffmpeg H264

Linux 系统资源查看及硬件故障排查(qbit)

qbit

操作系统 故障 资源

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