Redis缓存技术详解与实战
Redis缓存技术详解与实战
Redis作为一个开源的内存数据结构存储系统,它可以用作数据库、缓存和消息代理。在现代高并发、大数据量处理的系统中,Redis作为缓存层的应用越来越广泛。本文将详细讲解Redis在查询、添加缓存、更新缓存、缓存预热、缓存穿透、缓存雪崩、缓存击穿等场景下的应用及解决方案,并通过实例代码来加深理解。
1. 查询缓存
1.1 场景描述
在Web应用中,对于读多写少的场景,为了提升性能,我们通常会选择将热点数据放入Redis中进行缓存。当应用需要读取数据时,首先会尝试从Redis中获取,如果Redis中存在该数据,则直接返回;否则,从数据库中查询并放入Redis中。
1.2 如何使用redis
在应用程序中,当需要获取某个数据项时,首先会尝试从Redis缓存中获取。如果缓存中存在该数据项,则直接返回给应用程序,从而避免了访问后端数据库的开销。如果缓存中不存在该数据项,则从数据库中获取数据,并将其存储在Redis缓存中以备后用。
1.3 解决方案
import redis.clients.jedis.Jedis; public class RedisCache { private static final String REDIS_HOST = "localhost"; private static final int REDIS_PORT = 6379; private static Jedis jedis; static { jedis = new Jedis(REDIS_HOST, REDIS_PORT); } public static String getData(String key) { String data = jedis.get(key); if (data == null) { // 模拟从数据库查询数据 data = "Data from DB"; // 将数据存入Redis缓存 jedis.set(key, data); // 可以设置过期时间 jedis.expire(key, 60); // 60秒后过期 } return data; }
}
2. 添加缓存
2.1 场景描述
当数据发生更新时,为了保证缓存与数据库的一致性,我们需要将数据同步更新到Redis中。
2.2 如何使用redis
当有新数据需要存储时,可以直接将数据添加到Redis缓存中。这通常发生在数据首次被创建或修改时。将数据存储在Redis中可以使后续的数据访问更加快速。
2.3 解决方案
// 实际上,在查询缓存的示例中,如果Redis中没有数据,就已经包含了添加缓存的逻辑
// 但为了明确说明,这里再提供一个简单的添加缓存方法
public static void addData(String key, String value) { jedis.set(key, value); // 可以选择性地设置过期时间 jedis.expire(key, 60); // 60秒后过期
}
3. 更新缓存
3.1 场景描述
在某些场景下,我们可能需要对缓存的数据进行批量更新或定期更新。
3.2 如何使用redis
当数据发生变化时,需要更新Redis缓存中的相应项以确保缓存中的数据是最新的。这可以通过简单地使用Redis的SET命令(或相应的库函数)来实现,用新的数据值替换旧的数据值。
3.3 解决方案
public static void updateData(String key, String newValue) { // 假设newValue是新的数据值 jedis.set(key, newValue); // 可以选择性地更新过期时间 jedis.expire(key, 60); // 如果需要的话
}
4. 缓存预热
4.1 场景描述
在系统启动或低峰时段,为了提升后续访问的性能,我们可以预先将热点数据加载到Redis缓存中。
4.2 如何使用redis
缓存预热是在系统启动或低峰时段预先加载缓存数据的过程。通过预先加载数据到缓存中,可以确保在高峰时段应用程序可以更快地响应请求,因为所需的数据已经在缓存中可用。缓存预热通常涉及从数据库中读取数据并将其存储在Redis缓存中。
4.3 解决方案
编写一个预热脚本,在系统启动或低峰时段,将预计会被频繁访问的数据加载到Redis中。
public static void warmUpCache() { // 假设我们有一个需要预热的key列表 List<String> keysToWarmUp = Arrays.asList("key1", "key2", "key3"); for (String key : keysToWarmUp) { // 模拟从数据库查询数据 String data = "Data for " + key; // 将数据添加到Redis缓存中 jedis.set(key, data); // 设置过期时间(如果需要) jedis.expire(key, 60 * 60 * 24); // 一天后过期 }
}
5. 缓存穿透
5.1 场景描述
缓存穿透是指查询一个不存在的数据,由于缓存中不存在该数据,导致每次请求都会去数据库中查询,从而失去缓存的意义。
5.2 如何使用redis
缓存穿透是指查询一个不存在的数据,由于缓存中不存在该数据,因此每次查询都会去数据库查询,从而增加了数据库的负载。为了解决这个问题,可以使用布隆过滤器来快速判断一个数据是否存在于Redis缓存中。如果布隆过滤器判断该数据不存在于缓存中,则可以直接返回结果,而无需去数据库查询。
5.3 解决方案
-
布隆过滤器
使用布隆过滤器来过滤掉不存在的数据,减少对数据库的无效查询。 -
空值缓存
对于不存在的数据,在Redis中缓存一个空值或特殊标记,并设置一个较短的过期时间。
由于Java本身不直接支持布隆过滤器,但可以使用Google的Guava库或者Redis的Bitmaps来实现类似的功能。这里仅提供一个概念性的描述。
6. 缓存雪崩
6.1 场景描述
缓存雪崩是指缓存中大量数据同时过期,导致大量请求直接涌入数据库,给数据库带来巨大压力。
6.2 如何使用redis
缓存雪崩是指由于大量的缓存数据同时过期,导致大量的请求都去数据库查询,从而增加了数据库的负载。为了解决这个问题,可以采取以下几种策略:
- 随机过期时间:为缓存数据设置不同的过期时间,以避免大量的缓存数据同时过期。
- 缓存降级:当缓存不可用或查询压力过大时,可以临时关闭缓存查询,直接返回默认数据或执行一些降级逻辑。
- 缓存预热:在系统启动或低峰时段预先加载缓存数据,以减轻高峰时段的压力。
6.3 解决方案
-
随机过期时间
设置缓存过期时间时,避免大量数据同时过期,可以为每个key设置一个随机的过期时间。 -
降级策略
当数据库压力过大时,可以暂时关闭部分非核心功能,保证核心功能的正常运行。
在Java中,防止缓存雪崩的策略主要是确保缓存的key不是同时过期。
// 当设置缓存过期时间时,使用随机时间
public static void setWithRandomExpire(String key, String value) { int randomSeconds = 60 + new Random().nextInt(60 * 60); // 1分钟到1小时之间的随机时间 jedis.setex(key, randomSeconds, value);
}
7. 缓存击穿
7.1 场景描述
缓存击穿是指某个热点key突然过期,此时大量请求会涌入数据库,导致数据库压力骤增。
7.2 如何使用redis
缓存击穿是指某个热点数据的缓存突然失效,导致大量的请求都去数据库查询该数据。为了解决这个问题,可以使用锁或其他同步机制来确保只有一个请求去数据库查询数据,而其他请求则等待第一个请求返回数据并更新缓存。这样,其他请求就可以直接从缓存中获取数据,而无需再去数据库查询。
7.3 解决方案
-
互斥锁
在访问缓存之前,使用互斥锁(如Redis的SETNX命令)来确保只有一个请求能够去数据库中查询数据,其他请求则等待该请求将数据加载到缓存中。 -
热点数据永不过期
对于某些热点数据,可以设置其永不过期,或者设置一个较长的过期时间。
import java.util.concurrent.locks.ReentrantLock; public class CacheWithLock { private static final ReentrantLock lock = new ReentrantLock(); public static String getDataWithLock(String key) { String data = jedis.get(key); if (data == null) { lock.lock(); try { // 再次检查,防止其他线程已经加载了数据 data = jedis.get(key); if (data == null) { // 模拟从数据库查询数据 data = "Data from DB with lock"; // 将数据存入Redis缓存 jedis.set(key, data); // 设置过期时间 jedis.expire(key, 60); } } finally { lock.unlock(); } } return data; }
}
相关文章:
Redis缓存技术详解与实战
Redis缓存技术详解与实战 Redis作为一个开源的内存数据结构存储系统,它可以用作数据库、缓存和消息代理。在现代高并发、大数据量处理的系统中,Redis作为缓存层的应用越来越广泛。本文将详细讲解Redis在查询、添加缓存、更新缓存、缓存预热、缓存穿透、…...
业务架构的位置及关系
背景 我们已经了解了业务架构的核心元素组成,以及各个扩展元素,同时对各个元素的关系协同也有了一些了解,那么接下来,我们进一步在宏观层面来看业务架构与其他架构的关系。 企业架构 企业架构有多种理解,也有多种叫…...
CMS与AI的融合:构建万能表单小程序系统
引言: 随着人工智能技术的飞速发展,MyCMS作为一款功能强大的内容管理系统,通过集成AI技术,进一步拓展了其应用范围和智能化水平。本文将探讨如何利用MyCMS结合AI技术,构建一个能够将用户提交的万能表单数据转化为智能提…...
机器学习常见知识点 2:决策树
文章目录 决策树算法1、决策树树状图2、选择最优决策条件3、决策树算法过程→白话决策树原理决策树构建的基本步骤常见的决策树算法决策树的优缺点 【五分钟机器学习】可视化的决策过程:决策树 Decision Tree 关键词记忆: 纯度、选择最优特征分裂、熵、基…...
海洋CMS admin_notify.php 远程代码执行漏洞复现(CVE-2024-30565)
0x01 产品简介 海洋CMS是一套专为不同需求的站长而设计的内容管理系统,灵活、方便、人性化设计、简单易用是最大的特色,可快速建立一个海量内容的专业网站。海洋CMS基于PHP+MySql技术开发,完全开源免费 、无任何加密代码。 0x02 漏洞概述 海洋CMS admin_notify.php 接口处…...
Spring、Spring MVC、MyBatis和Spring Boot对比
在对比Spring、Spring MVC、MyBatis和Spring Boot时,我们可以从以下几个方面进行详细的分析: Spring框架: 作用:Spring是一个轻量级的IoC(控制反转)和AOP(面向切面编程)容器&#…...
【Linux高级IO】select、poll、epoll
【Linux高级IO】select、poll、epoll toc 作者:爱写代码的刚子 时间:2024.6.5 前言:本篇博客将会介绍面试重点考察的select、poll、epoll IO: input && Output read && write 应用层read&&write的时候,…...
Etcd Raft架构设计和源码剖析2:数据流
Etcd Raft架构设计和源码剖析2:数据流 | Go语言充电站 前言 之前看到一幅描述etcd raft的流程图,感觉非常直观,但和自己看源码的又有些不同,所以自己模仿着画了一下,再介绍一下。 下图从左到右依次分为4个部分&…...
深入理解Qt多线程编程(QThreadPool)
多线程编程在现代软件开发中变得越来越重要,它能够提高应用程序的响应速度和处理性能。在Qt框架中,QThreadPool作为线程池管理工具,被频繁的使用。 目录 概述 接口介绍 底层原理解析 使用方法 概述 QThreadPool是Qt提供的一个线程池实现&a…...
Prisma数据库ORM框架学习
初始化项目 中文网站 点击快速开始,点击创建sql项目,后面一步一步往后走 这个博主也挺全的,推荐下 可以看这个页面初始化项目跟我下面是一样的,这里用得是ts,我下面是js,不需要额外的配置了 1.vscode打开一个空文件夹 2.npm init -y 初始化package.json 3.安装相关依赖 …...
Flutter-使用MethodChannel 实现与iOS交互
前言 使用 MethodChannel 在 Flutter 与原生 Android 和 iOS 之间进行通信,可以让你在 Flutter 应用中调用设备的原生功能。 基础概念 MethodChannel:Flutter 提供的通信机制,允许消息以方法调用的形式在 Flutter 与原生代码之间传递。方法…...
【星海随笔】云解决方案学习日志篇(一) ELK,kibana,Logstash安装
心路历程 本来想最近再研究研究DPDK的。但是自己做一个东西很多时候没有回报。因为自己的低学历问题,类似工作的面试都没有。所以很多东西学了很快就忘了,没有地方可以用。 今天看到了一个大佬,除了发型外,很多想法还是很共鸣的。 Shay Banon 决定开始跟…...
【leetcode】hot100 哈希表
1. 两数之和 1.1 题目 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。…...
每日5题Day22 - LeetCode 106 - 110
每一步向前都是向自己的梦想更近一步,坚持不懈,勇往直前! 第一题:106. 从中序与后序遍历序列构造二叉树 - 力扣(LeetCode) class Solution {public TreeNode buildTree(int[] inorder, int[] postorder) {…...
【Python】读取文件夹中所有excel文件拼接成一个excel表格 的方法
我们平常会遇到下载了一些Excel文件放在一个文件夹下,而这些Excel文件的格式都一样,这时候需要批量这些文件合并成一个excel 文件里。 在Python中,我们可以使用pandas库来读取文件夹中的所有Excel文件,并将它们拼接成一个Excel表…...
7. 通配符和正则表达式
文章目录 7.1 通配符7.1.1 通配符介绍7.1.2 通配符示例 7.2 正则表达式7.2.1 grep命令7.2.2 基本正则表达式7.2.3 扩展正则表达式 7.1 通配符 在 Shell 中通配符用于查找文件名和目录名。它是由 Shell 处理的,只会出现在命令的参数中。 7.1.1 通配符介绍 * 匹…...
ROS2底层机制源码分析
init ->init_and_remove_ros_arguments ->init ->Context::init 保存初始化传入的信号 ->install_signal_handlers→SignalHandler::install 开线程响应信号 ->_remove_ros_arguments 移除ros参数 ->SingleNodeManager::instance().…...
超越 Transformer开启高效开放语言模型的新篇章
在人工智能快速发展的今天,对于高效且性能卓越的语言模型的追求,促使谷歌DeepMind团队开发出了RecurrentGemma这一突破性模型。这款新型模型在论文《RecurrentGemma:超越Transformers的高效开放语言模型》中得到了详细介绍,它通过…...
快速排序-Hoare 递归版 C语言
个人主页点这里~ 快速排序的简介: 快速排序是Hoare于1962年提出的一种 二叉树结构 的 交换 排序方法,其基本思想为:任取待排序元素序列中 的某元素作为 基准值 ,按照该排序码将待排序集合分割成 两子序列 , 左子序列中所有元素均 …...
C语言经典指针运算笔试题图文解析
指针运算常常出现在面试题中,画图解决是最好的办法。 题目1: #include <stdio.h> int main() {int a[5] { 1, 2, 3, 4, 5 };int* ptr (int*)(&a 1);printf("%d,%d", *(a 1), *(ptr - 1));return 0; } //程序的结果是什么&…...
使用 KubeKey v3.1.1 离线部署原生 Kubernetes v1.28.8 实战
今天,我将为大家实战演示,如何基于操作系统 openEuler 22.03 LTS SP3,利用 KubeKey 制作 Kubernetes 离线安装包,并实战离线部署 Kubernetes v1.28.8 集群。 实战服务器配置 (架构 1:1 复刻小规模生产环境,配置略有不…...
DOS 命令
Dos: Disk Operating System 磁盘操作系统, 简单说一下 windows 的目录结构。 ..\ 到上一级目录 常用的dos 命令: 查看当前目录是有什么内容 dir dir d:\abc2\test200切换到其他盘下:盘符号 cd : change directory 案例演示:切换…...
如何用Java程序实现一个简单的消息队列?
在Java程序中,可以使用内置的java.util.concurrent.BlockingQueue作为消息队列存放的容器,来实现一个简单的消息队列。 具体实现如下,在这个例子中,我们创建了一个生产者线程和一个消费者线程,他们共享同一个阻塞队列…...
OpenAI 宕机事件:GPT 停摆的影响与应对
引言 2024年6月4日,OpenAI 的 GPT 模型发生了一次全球性的宕机,持续时间长达8小时。此次宕机不仅影响了OpenAI自家的服务,还导致大量用户涌向竞争对手平台,如Claude和Gemini,结果也导致这些平台出现故障。这次事件的广…...
linux常用的基础命令
ls - 列出目录内容。 cd - 更改目录。 pwd - 打印当前工作目录。 mkdir - 创建新目录。 rmdir - 删除空目录。 touch - 创建新文件或更新现有文件的时间戳。 cp - 复制文件或目录。 mv - 移动或重命名文件或目录。 rm - 删除文件或目录。 cat - 显示文件内容。 more - 分页显示…...
618家用智能投影仪推荐:这个高性价比品牌不容错过
随着科技的不断进步,家庭影院的概念已经从传统的大屏幕电视逐渐转向了更为灵活和便携的家用智能投影仪。随着618电商大促的到来,想要购买投影仪的用户们也开始摩拳擦掌了。本文将从投影仪的基础知识入手,为您推荐几款性价比很高的投影仪&…...
自愿离婚协议书
自愿离婚协议书 男方(夫): 女方(妻): 双方现因 原因,导致夫妻情感已破裂,自愿离婚…...
WPS JSA 宏脚本入门和样例
1入门 WPS window版本才支持JSA宏的功能。 可以自动化的操作文档中的一些内容。 参考文档: WPS API 参考文档:https://open.wps.cn/previous/docs/client/wpsLoad 微软的Word API文档:Microsoft.Office.Interop.Word 命名空间 | Microsoft …...
Printing and Exporting
打印 大多数DevExpress。NET控件(XtraGrid、XtraPivotGrid、XttraTreeList、XtraScheduler、XtraCharts)提供打印和导出功能。 所有可打印的DevExpress.NET控件是使用XtraPrinting库提供的方法打印的。 若要确定预览和打印选项是否可用,请检…...
c++【入门】正多边形每个内角的度数
限制 时间限制 : 1 秒 内存限制 : 128 MB 题目 根据多边形内角和定理,正多边形内角和等于:(n - 2)180(n大于等于3且n为整数)(如下图所示是三角形、四边形、五边形、六边形的形状)…...
做网站的软件dw/免费建网站
PPP-C#conf tPPP-C(config)#vpdn enable //启用路由器的虚拟专用拨号网络---***d 由于ADSL的PPPoE应用是通过虚拟拨号来实现的所以在路由器中需要使用VPDN的功能PPP-C(config)#int e1/0 // 路由器内网接口PPP-C(config-if)#no shutPPP-C(config-if)#i…...
虚拟主机购买网站/网站制作公司高端
第三章计算机基本操作一、单项选择题1、计算机感染病毒后会产生各种现象,以下不属于病毒现象的是(www.TopS)A、文件占用的空间变大B、发生异常蜂鸣声C、屏幕显示异常图形D、机内的电扇不转2、Windows支持下面(www.TopS)网络协议A、Net? BEUTB、IPX/SPXC、TCP/IPD、…...
哪些网站可以兼职做设计/5g站长工具seo综合查询
1、概念 Object类是所有类的父类,也就是说任何一个类的定义的时候如果没有明确的继承一个父类的话,那么它就是Object的子类。既然Object是所有类的父类,那么最大的一个好处就在于:利用Object类可以接收全部类的对象,因…...
wordpress网站自动伪原创/seo优化神器
KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法)。KMP算法的关键是利用匹配失败后的信息,尽量减少模式串与主串…...
上海正规网站建设耗材/合肥网络推广软件
场景开发中经常需要用到定时任务,对于商城来说,定时任务尤其多,比如优惠券定时过期、订单定时关闭、微信支付2小时未支付关闭订单等等,都需要用到定时任务,但是定时任务本身有一个问题,一般来说我们都是通过…...
wordpress 获取指定分类/大片网站推广
文章目录循环判断try...catch...end中断?继续?返回?error()命令与warning()命令再提程序分块循环 for…end >> for i1:4disp(i) end1234 >> for iabd disp(i) end a b dwhile…end >> var1; while var disp(var) varinpu…...