OceaBase开发者大会落地上海!4月20日共同探索数据库前沿趋势!报名戳 了解详情
写点什么

使用 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:032434

评论

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

微信朋友圈高性能复杂度分析

缘分呐

微信朋友圈 高性能架构

CPU 功能

Changing Lin

9月日更

模块七作业

king

头一次见,阿里大牛把计算机网络协议讲得这么有趣,已火爆Github

Java~~~

Java 架构 面试 网络协议 计算机

北鲲云超算平台能够为药物研发提供哪些层面的解决方案?

北鲲云

ipfs矿机工作原理是什么?ipfs矿机怎么买?

ipfs矿机怎么买 ipfs矿机工作原理是什么

Python代码阅读(第24篇):根据筛选函数将列表元素分成两组

Felix

Python 编程 Code Programing 阅读代码

不愧是华为内部的“操作系统学习笔记”,一篇说细节,一篇讲哲学

Java~~~

Java 架构 面试 操作系统 网络

Socket接口固定QPS性能测试实践

FunTester

socket 性能测试 接口测试 测试框架 FunTester

fil大涨:fil币价格行情怎样?投资fil靠谱吗?Fil多长时间能回本?

区块链 FIL币价格今日行情 fil挖矿靠谱吗 fil挖矿多久能回本? 投资filecoin

ipfs挖矿市场即将爆发 ipfs挖矿原理是什么?ipfs挖矿值得投资吗?

IPFS挖矿值得投资吗 ipfs挖矿原理是什么

不愧是阿里内部“SpringCloudAlibaba学习笔记”从头到尾,都是精华

Java 架构 面试 微服务

Java + opencv 实现年龄识别

张音乐

Java OpenCV 9月日更 年龄识别

银行对公业务数字化迎来新机遇

CECBC

微信朋友圈的高性能复杂度分析

晓波

架构实战营

美团面试:说说MySQL存储引擎原理,幸好我准备过!

Java MySQL 程序员 面试 计算机

逆袭!裸辞26天,历经4面,60w“跳”进鹅厂(附面试流程和真题)

Java~~~

Java 架构 面试 微服务 JVM

链路性能测试中参数多样性方法分享

FunTester

性能测试 测试框架 全链路测试 FunTester 链路测试

GitHub标星翻倍!阿里大牛呕心沥血终成39w字Java面试笔记

Java~~~

Java 架构 面试 微服务 多线程

量化策略交易平台开发,马丁策略交易系统源码搭建

13530558032

微信业务架构分析

黑鹰

微信业务架构

模块二作业

potti

架构实战营

GitHub上霸榜多时的“大哥”!竟是Alibaba内部被疯狂转载的Spring全能指南?

Java 编程 架构 面试 springboot

单链路性能测试实践

FunTester

性能测试 接口测试 测试框架 压力测试 全链路测试

【LeetCode】二叉搜索树的最近公共祖先Java题解

Albert

算法 LeetCode 9月日更

Linux内核时钟机制及调度算法

hanaper

网络攻防学习笔记 Day126

穿过生命散发芬芳

主机安全 9月日更

LeetCode刷题35-简单-搜索插入位置

ベ布小禅

9月日更

膜拜!清华大佬手撸多线程并发源码笔记Github上线3天星标35k+

Java~~~

Java 架构 面试 JVM 多线程

ipfs分布式存储技术的优势在哪里?ipfs即将取代http是真的吗?

区块链 分布式存储 IPFS ipfs到底能否取代http?

Vue进阶(九十一):自定义指令

No Silver Bullet

Vue 9月日更

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