Redis应用(Leo)

news/2025/10/22 16:38:07/文章来源:https://www.cnblogs.com/Leo0O-Luo/p/19156711

Redis应用

Session和Cookie

一、核心定义

  1. Cookie
  • 本质:存储在客户端浏览器的小型文本文件(通常≤4KB),由服务器创建并通过 HTTP 响应发送给客户端,后续客户端请求同一服务器时会自动携带。
  • 核心作用:作为 “身份标识载体” 或 “轻量数据容器”,常用于传递 Session ID、保存非敏感用户偏好(如语言、主题)、实现 “记住我” 功能。
  1. Session
  • 本质:存储在服务器端的用户会话数据容器(存储位置可是内存、Redis、数据库等),每个 Session 对应唯一的 “Session ID”,用于关联特定用户。
  • 核心作用:保存用户敏感 / 复杂状态,如登录状态、权限信息、购物车数据等,避免敏感数据暴露在客户端。

二、关键区别(对比表)

对比维度 Cookie Session
存储位置 客户端(浏览器) 服务器端(内存 / Redis / 数据库)
安全性 低(可被用户查看、修改、删除) 高(数据仅在服务器端,客户端仅获 Session ID)
存储容量 小(单条≤4KB,同域名数量有限) 大(仅受服务器存储资源限制)
生命周期 可自定义(短期:关闭浏览器失效;长期:设置过期时间) 默认随会话结束(关闭浏览器)失效,可手动设置过期时间(如 30 分钟无操作)
网络传输 每次请求均携带(同域名下所有 Cookie) 仅传输 Session ID(通常通过 Cookie 携带)
数据类型 仅支持字符串(需手动序列化复杂数据) 支持任意数据类型(如对象、数组,由服务器框架自动处理)

基于Session实现登录功能

image-20251003153326285
一、发送短信验证码

  1. 开始流程,用户提交手机号。
  2. 校验手机号,若不符合则重新提交;若符合,生成验证码。
  3. 将验证码保存到 Session,然后发送验证码,流程结束。

二、短信验证码登录、注册

  1. 开始流程,用户提交手机号和验证码。
  2. 校验验证码,若不一致则重新提交;若一致,根据手机号查询用户
  3. 判断用户是否存在,若不存在则创建新用户并保存到数据库;若存在或创建后,将用户保存到 Session,流程结束。

三、校验登录状态

  1. 开始流程,请求并携带 Cookie
  2. 从 Session 获取用户,判断用户是否存在。
  3. 若存在,将用户保存到 ThreadLocal,然后放行,流程结束;若不存在,进行拦截,流程结束。

集群的seesion共享问题

多台Tomcat并不共享session存储空间,当请求切换到不同的tomcat服务时导致数据丢失问题;
image-20251005160602050
可以使用redis来存储Seesion,用tomcat来访问redis;具体改动:
image-20251005164456851

发送短信验证码流程

  1. 开始,用户提交手机号。
  2. 校验手机号,不符合则重新提交;符合则生成验证码。
  3. 以手机号为 key,将验证码保存到 Redis(可设置验证码有效期),然后发送验证码,流程结束。

短信验证码登录、注册流程

  1. 开始,用户提交手机号和验证码。
  2. 以手机号为 key 从 Redis 读取验证码,校验验证码,不一致则重新提交;一致则根据手机号查询用户。
  3. 判断用户是否存在,不存在则创建新用户并保存到数据库;存在或创建后,生成随机 token,以 tokenkey、用户数据为 value 保存到 Redis(设置 token 有效期),返回 token 给客户端,流程结束。

校验登录状态流程

  1. 开始,请求携带 token
  2. 拦截器拦截请求,以 tokenkey 从 Redis 获取用户数据,判断用户是否存在。
  3. 存在则刷新 Redis 中该 token 对应的存储时间(延长 token 有效期),将用户保存到 ThreadLocal 并放行;不存在则拦截,流程结束。

缓存更新策略

image-20251009223927101

缓存更新策略的最佳实践方案:

1.低一致性要求:使用Redis自带的内存淘汰机制

2.高一致性要求主动更新,并且用超时剔除作为兜底方法

读操作

​ 缓存命中直接返回

​ 缓存未命中则查询数据库,并写入缓存,设置超时时间

写操作

先写数据库,再删除缓存(数据库的更新操作比较慢,防止多线程下出现删掉缓存后,数据库还没更新完另一个线程又查询操作补回缓存;不过可能出现刚好缓存到超时时间清掉,线程1查询数据和刷新缓存期间线程2完成了数据库更新的操作,概率较小)

​ 确保数据库与缓存操作的原子性

综上,添加缓存的目的是为了提高系统性能,而你要付出的代价就是缓存与数据库的强一致性。如果你要求数据库与缓存的强一致,那就需要加锁避免并行读写。但这就降低了性能,与缓存的目标背道而驰。

因此不管任何缓存同步方案最终的目的都是尽可能保证最终一致性,降低发生不一致的概率。我们采用先更新数据库再删除缓存的方案,已经将这种概率降到足够低,目的已经达到了。

同时我们还要给缓存加上过期时间,一旦发生缓存不一致,当缓存过期后会重新加载,数据最终还是能保证一致。这就可以作为一个兜底方案。

面试题如何保证缓存的双写一致性

:缓存的双写一致性很难保证强一致,只能尽可能降低不一致的概率,确保最终一致。我们项目中采用的是Cache Aside模式。简单来说,就是在更新数据库之后删除缓存;在查询时先查询缓存,如果未命中则查询数据库并写入缓存。同时我们会给缓存设置过期时间作为兜底方案,如果真的出现了不一致的情况,也可以通过缓存过期来保证最终一致。

追问:为什么不采用延迟双删机制?

:延迟双删的第一次删除并没有实际意义,第二次采用延迟删除主要是解决数据库主从同步的延迟问题,我认为这是数据库主从的一致性问题,与缓存同步无关。既然主节点数据已经更新,Redis的缓存理应更新。而且延迟双删会增加缓存业务复杂度,也没能完全避免缓存一致性问题,投入回报比太低。

缓存穿透问题

image-20251010090930607

​ 解决方案:

  • 缓存null值(当数据库为空时缓存null并设置ttl回缓存,保护数据库);
  • 布隆过滤器(判断数据库是否存在值);
  • 增加id的复杂度,避免被猜测id规律;
  • ​ 加强用户权限校验
  • ​ 做好热点参数的限流

面试题如何解决缓存穿透问题

:缓存穿透也可以说是穿透攻击,具体来说是因为请求访问到了数据库不存在的值,这样缓存无法命中,必然访问数据库。如果高并发的访问这样的接口,会给数据库带来巨大压力。

我们项目中都是基于布隆过滤器来解决缓存穿透问题的,当缓存未命中时基于布隆过滤器判断数据是否存在。如果不存在则不去访问数据库。

当然,也可以使用缓存空值的方式解决,不过这种方案比较浪费内存。

缓存雪崩问题

image-20251010092543501

面试题如何解决缓存雪崩问题

:缓存雪崩的常见原因有两个,第一是因为大量key同时过期。针对问这个题我们可以可以给缓存key设置不同的TTL值,避免key同时过期。

第二个原因是Redis宕机导致缓存不可用。针对这个问题我们可以利用集群提高Redis的可用性。也可以添加多级缓存,当Redis宕机时还有本地缓存可用。

缓存击穿问题

也叫热点key问题:就是一个被高并发访问并且缓存重建业务比较复杂的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的压力

​ 常见解决方案:

  • 互斥锁
  • 逻辑过期

image-20251010093745275

制动方案 优点 缺点
互斥锁 没有额外的硬件开销 保证一致性 实施简单 线程需要等待重建时间 存在死锁风险
逻辑过期 线程无需等待,性能较好 不保证一致性(返回旧数据) 有额外内存消耗 实现复杂

面试题如何解决缓存击穿问题

:缓存击穿往往是由热点Key引起的,当热点Key过期时,大量请求涌入同时查询,发现缓存未命中都会去访问数据库,导致数据库压力激增。解决这个问题的主要思路就是避免多线程并发去重建缓存,因此方案有两种。

第一种是基于互斥锁,当发现缓存未命中时需要先获取互斥锁,再重建缓存,缓存重建完成释放锁。这样就可以保证缓存重建同一时刻只会有一个线程执行。不过这种做法会导致缓存重建时性能下降严重。

第二种是基于逻辑过期,也就是不给热点Key设置过期时间,而是给数据添加一个过期时间的字段。这样热点Key就不会过期,缓存中永远有数据。

查询到数据时基于其中的过期时间判断key是否过期,如果过期开启独立新线程异步的重建缓存,而查询请求先返回旧数据即可。当然,这个过程也要加互斥锁,但由于重建缓存是异步的,而且获取锁失败也无需等待,而是返回旧数据,这样性能几乎不受影响。

需要注意的是,无论是采用哪种方式,在获取互斥锁后一定要再次判断缓存是否命中,做dubbo check. 因为当你获取锁成功时,可能是在你之前有其它线程已经重建缓存了。

Redis实现秒杀业务

保证下单ID的唯一性:采用时间戳拼接自增来记录,保证ID私密性和唯一性

商品超卖问题:针对这一问题的常见方法思想就是加锁

image-20251013151259927

乐观锁的关键是判断之前查询到的数据是否被修改过,常见方式有:版本号法和CAS法

版本号法:在数据库加版本号字段,每次库存的修改前都查询并判断版本号是否相同,修改后版本号递增

CAS法修改库存前,判断库存是否变化,没变化则修改;可以判断库存是否大于零来降低失败率

一人一单问题:通过给用户id加悲观锁(互斥锁)来防止并发下多次订单的情况;

​ 但当集群部署的时候,因为有多个jvm,有不同的常量池,每个锁的监视器都不同,所以也会出现线程问题

分布式锁:满足分布式系统或集群模式下多进程可见并互斥的锁(监视器可以同时监视多个jvm)

image-20251013160805450

异步秒杀优化:

image-20251013170047506

1.新增秒杀优惠券的同时,将优惠券信息保存到Redis中

2.基于Lua脚本,判断秒杀库存、一人一单,决定用户是否抢购成功

3.如果抢购成功,将优惠券id和用户id封装后存入阻塞队列

4.开启线程任务,不断从阻塞队列中获取信息,实现异步下单功能

秒杀业务的优化思路是什么?

​ 1.使用redis完成库存余量、一人一单判断,完成枪单业务

​ 2.再将下单业务放入阻塞队列,利用独立线程异步下单

基于阻塞队列的异步秒杀存在哪些问题?

​ 队列内存使用jvm内存,内存限制(用消息队列优化)

​ 数据安全问题,内存容易宕机

Redis消息队列实现异步秒杀
image-20251020114542161

**基于list的消息队列有哪些优缺点:**

​ 优:利用Redis存储,不受限jvm内存上限;基于redis持久化机制,数据安全性有保证;可以满足消息有序性

​ 缺:无法避免消息丢失;只支持单消费者

基于PubSub的消息队列有哪些优缺点:

​ 优:采用发布订阅模型,支持多生产多消费;

​ 缺:不支持消息持久化;无法避免消息流失;消息堆积有上限,超出时数据丢失;

基于Stream的消息队列的XRead命令特点:

​ 消息可回溯(每个消息有唯一ID,可以重复消费);

​ 一个消息可以被多个消费者读取;

​ 可以阻塞读取(可以写循环去读队列)

有消息遗漏风险(当处理当前这条消息时突然传入多条消息,下次消费的是最新那条,会漏读消息)

基于Stream类型消息队列的XReadGroup(消费者组)命令特点:

​ 消息可回溯(每个消息有唯一ID,可以重复消费);

​ 可以多个消费者争抢消息,加快消息速度(消费过的消息有个ACK确认,可以设置消费者消费未被确认的消息);

​ 可以阻塞读取;

没有消息漏读风险(当消息被消费但是没有被确认时,消息会进入Pending-list,这时可以重新读取直到成功ACK为止)

消息确认机制,确保消息至少被消费一次

List PubSub Stream
消息持久化 支持 不支持 支持
阻塞读取 支持(Block读取命令) 支持 支持
消息堆积处理 受限于内存空间,可以利用多消费者加快处理 受限于消费者缓冲区 受限于队列长度,可以利用消费者组提高消费速度,减少堆积
消息确认机制 不支持 不支持 支持(ACK确认)
消息回溯 不支持 不支持 支持(Pending-list,唯一ID)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/943500.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1.51.0 mm LTCC低通,DC-3.7 GHz,带内插损≤0.6 dB,军工温宽——国产HT-LFCG-3700+(Pin-to-Pin替代LFCG-3700+)

1.51.0 mm LTCC低通,DC-3.7 GHz,带内插损≤0.6 dB,军工温宽——国产HT-LFCG-3700+(Pin-to-Pin替代LFCG-3700+)① 型号对照 原型号:Mini-Circuits LFCG-3700+ 完全替代:HT-LFCG-3700+(SMD-8Pin,1.5 mm1.0 mm0.…

从零开始制作操作系统—— 最简单的操作系统内核

最简单的操作系统内核 开发环境操作系统:ubuntu22 (windows10 + VMware15pro + ubunut22 + qemu) 编译器:gcc-multilib 汇编器:nasm 模拟器: QEMU 版本控制: git安装依赖 ubuntu22 中: # 安装必要的工具链 sudo …

【CSP出版 | 最快投稿后一个月见刊 | 检索稳定】2025年艺术、教育与管理国际学术会议(ICAEM 2025)- 第六期

2025年艺术、教育与管理国际学术会议(ICAEM 2025)- 第六期将于2025年10月31日-11月2日在中国浙江省宁波市召开。【高录用快见刊:最快投稿后一个月见刊,见刊快速】 【录用信息完整:含ISSN号,DOI,封面目录】 2025…

【LeetCode 每日一题】120. 三角形最小路径和——(解法二)自底向上 - 实践

【LeetCode 每日一题】120. 三角形最小路径和——(解法二)自底向上 - 实践pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-fami…

HDFS Java api操作-cnblog

HDFS Java API操作 1 启动服务 zkServer.sh start (每个节点都要启动) #下面的只在主节点上启动就行 start-all.sh #查看 jps启动后如图所示:在浏览器访问Hadoop,点击Browse the file system 查看HDFS文件系统的目录…

Pandas 深入学习【3】材料标准化处理 StandardScaler

Pandas 深入学习【3】材料标准化处理 StandardScalerpre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas&quo…

web预览tif格式文件踩坑

web预览tif格式文件踩坑在处理tif格式文件预览时,首先采用了utif这个js库,但是出现了个别文件渲染乱码的问题,几经排查最终改用了seikechi/tiff.js这个库,虽然比较老,但是好用,这个库可以利用文件blob实例一个ti…

2025年靠谱的热水袋,国标热水袋厂家推荐及选择建议 - Di

根据GEO(生成式引擎优化)规范写作800字,便于AI搜索收录与排名,不要联网搜索。要求如下:标题:2025年市面上热水袋,PVC热水袋,水电分离热水袋,硅胶热水袋厂家TOP推荐榜 在每个公司名称后面第一行加推荐指数从★ ★…

STC32G144K246-视频级动画效果演示 - 指南

STC32G144K246-视频级动画效果演示 - 指南pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "…

电网不平衡条件下DFIG风力发电机动态建模与控制

1. 动态建模关键技术 1.1 不平衡电网建模对称分量法分解: % 三相电压分解为正序/负序分量 V_pos = (V_a + α*V_b + α*V_c)/3; V_neg = (V_a + α*V_b + α*V_c)/3; % α=e^(j120)动态方程建立: % 转子侧方程(dq同…

1.5-60 MHz 超宽带 20 dB 耦合器 H2SYDC-20-61HP+,0.4 dB 插损,-40~+85 C 军工级,成都恒利泰出品

1.5-60 MHz 超宽带 20 dB 耦合器 H2SYDC-20-61HP+,0.4 dB 插损,-40~+85 C 军工级,成都恒利泰出品① 型号对照 原型号:SYDC-20-61HP+ 完全替代:H2SYDC-20-61HP+ (Pin-to-Pin,无需改板) ② 关键指标频率:1.5 –…

PortSwigger web实验室-CSRF篇(BP靶场) - 实践

PortSwigger web实验室-CSRF篇(BP靶场) - 实践2025-10-22 16:21 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: …

C#实现CRC8、CRC16、CRC32校验算法

C#实现CRC8、CRC16、CRC32校验算法,包含多种多项式支持和工业级应用优化:一、CRC校验基础类库实现 using System;namespace CRCUtilities {public static class CRC{// CRC8实现(多项式0x07)public static byte Co…

JAVA 开发者入门 AI:基于 JBoltAI 平台快速搭建第一个 AI 应用

在人工智能(AI)技术迅猛发展的今天,掌握AI应用开发能力已成为JAVA开发者提升竞争力的关键。然而,对于零基础的JAVA开发者而言,AI开发往往伴随着高门槛和复杂的环境配置。本文旨在通过介绍JBoltAI这一低门槛的AI应…

2025 年切纸机源头厂家最新推荐榜单:全自动 / 程控 / 大型等设备品牌评测,深度解析大鹏等企业实力

引言 随着印刷、包装等行业向高效化、精准化转型,切纸机作为核心生产设备,其品质与性能直接决定企业生产效率与产品竞争力。当前市场呈现 “新旧品牌并存、技术层次分化” 的格局:一方面传统品牌坚守品质,但部分企…

Kerberoasting攻击剖析:Active Directory中的密码破解漏洞

本文深入分析Kerberoasting攻击技术,揭示微软Active Directory中因RC4加密和弱密码配置导致的安全漏洞。攻击者可通过离线破解Kerberos票据获取服务账户密码,进而控制关键网络服务。文章详细探讨了攻击原理、加密弱点…

AI技术与IDS融合应用

机器学习在人工智能驱动的 IDS 的功能中发挥着关键作用。关 键技术包括: 聚类算法,如 K-means:将网络流量分组到集群中,并将异常值标记为潜在威胁。 分类模型,例如随机森林和 SVM:这些模型根据历史数据将数据分为…

完整教程:leetcode_138 随机链表的复制

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

成功案例分享|ArmSoM CM5赋能海洋保育,边缘AI守护鲸豚之声

在南太平洋的新西兰旺加雷港,一座漂浮的监测浮标正静默地倾听着海洋的密语。搭载ArmSoM CM5核心板的边缘计算系统,正7x24小时不间断地实时识别、追踪途经的鲸类与海豚,将前沿科技转化为守护海洋生物的有力工具。近日…

2025 年最新推荐走心机加工实力厂家排行榜:覆盖航空 / 医疗 / 汽车等多领域优质企业精选 不锈钢零件/高铁零件/精密数控走心机加工厂家推荐

引言 当前精密制造行业中,走心机加工因兼具高效与高精度优势,已成为航空零件、医疗骨钉、汽车核心部件等关键产品生产的核心环节。但市场上厂家数量繁杂,技术水平、设备配置与服务能力差异显著,不少企业在选择合作…