大数据 -38 Redis 分布式缓存 详细介绍 缓存、读写、旁路、穿透模式

点一下关注吧!!!非常感谢!!持续更新!!!
🚀 AI 篇持续更新中!(长期更新)
AI 炼丹日志-29 - 字节跳动 DeerFlow 深度研究框斜体样式架 私有部署 测试上手 架构研究,持续打造实用 AI 工具指南!📐🤖
💻 Java 篇正式开启!(300 篇)
目前 2025 年 07 月 10 日更新到:Java-68 深入浅出 分布式服务 Netty 实现自定义 RPC 附详细代码 MyBatis 已完结,Spring 已完结,Nginx 已完结,Tomcat 已完结,分布式服务正在更新!深入浅出助你打牢基础!
📊 大数据板块已完成多项干货更新(300 篇):
包括 Hadoop、Hive、Kafka、Flink、ClickHouse、Elasticsearch 等二十余项核心组件,覆盖离线+实时数仓全栈!大数据-278 Spark MLib - 基础介绍 机器学习算法 梯度提升树 GBDT 案例 详解

章节内容
上一节我们完成了:
HBase Maven 工程 POM 引入
HBase JavaAPI
HBase Java 实现 增、删、改、查
背景介绍
这里是三台公网云服务器,每台 2C4G,搭建一个 Hadoop 的学习环境,供我学习。
2C4G 编号 h121
2C4G 编号 h122
2C2G 编号 h123

Redis 简介
Redis(Remote Dictionary Server)是一个开源的、高性能的键值对存储系统,采用 C 语言开发。它支持多种数据结构,可用作数据库、缓存和消息中间件。Redis 以其出色的性能著称,能够处理高吞吐量的数据操作,被广泛应用于 Web 应用、实时分析、游戏开发等领域。
主要特点:
内存存储:数据主要存储在内存中,读写速度极快
持久化支持:提供 RDB 和 AOF 两种持久化机制
丰富的数据结构:支持字符串、哈希、列表等多种数据结构
高可用性:支持主从复制和哨兵模式
事务支持:通过 MULTI/EXEC 命令实现简单事务
官方网站为:
Redis 数据类型
Redis 支持五种核心数据类型,每种类型都有特定的使用场景和操作命令:
1. 字符串类型(String)
最基本的数据类型,可以存储字符串、整数或浮点数。最大能存储 512MB。典型应用场景:
缓存简单数据
计数器(如页面访问量)
分布式锁
2. 散列类型(Hash)
适合存储对象,由字段-值对组成。每个哈希可以存储 4 亿多个字段-值对。典型应用场景:
存储用户对象(用户名、年龄等信息)
购物车数据
3. 列表类型(List)
有序的字符串集合,按照插入顺序排序。支持从两端插入/删除元素。典型应用场景:
消息队列
最新动态展示
粉丝列表
4. 集合类型(Set)
无序的字符串集合,不允许重复元素。支持集合运算(交集、并集等)。典型应用场景:
标签系统
共同好友
去重统计
5. 有序集合类型(Sorted Set)
每个元素都关联一个分数(score),用于排序。元素唯一,但分数可以重复。典型应用场景:
排行榜
带权重的队列
范围查询
缓存场景
DB 缓存
DB 缓存是一种常见的缓存策略,主要用于减轻数据库服务器的压力。在常规的 Web 应用架构中,数据通常直接存储在关系型数据库中(如 MySQL、PostgreSQL 等),应用程序通过 SQL 查询直接与数据库交互。
随着业务增长和访问量上升,数据库可能成为系统瓶颈。当单日访问量达到上万级别时,数据库的读写压力会显著增加,可能导致查询响应变慢、连接池耗尽等问题。此时引入缓存机制可以有效缓解数据库压力。
典型应用场景
高频读取数据:如电商网站的商品详情、新闻站点的热门文章等
计算结果缓存:如统计报表、聚合查询结果
会话数据存储:用户登录状态、购物车信息等
解决方案
基础缓存方案
对象缓存:将数据库查询结果以键值对形式存储在 Redis/Memcached 中
查询缓存:缓存完整 SQL 语句及其结果
延迟写:先更新缓存,异步批量写入数据库
进阶架构优化
读写分离
主库负责写操作,多个从库负责读操作
通过 binlog 复制保持数据一致性
适用于读写比例较高的场景(如 8:2)
分库分表
垂直分库:按业务领域拆分(如用户库、订单库)
水平分表:单表数据按规则分散(如按用户 ID 哈希)
需要处理分布式事务、跨库查询等问题
缓存策略选择
Cache-Aside:先查缓存,未命中再查 DB
Write-Through:同时更新缓存和 DB
Write-Behind:先更新缓存,异步写入 DB
实施注意事项
缓存失效策略(TTL 设置)
缓存雪崩/穿透防护
数据一致性保证
监控缓存命中率
通过合理设计缓存策略,可以在保证数据一致性的前提下,将数据库 QPS 降低 50%-90%,显著提升系统性能。

数据库
的文件是在硬盘中
,与内存
做交换
。对于大量瞬时访问
,会导致频繁IO
而无法工作
。
Session 分离
传统 Session 管理机制的问题
在传统的 Java Web 应用中,Session 是由 Tomcat 容器自行维护和管理的。这种机制在单机环境下运行良好,但在集群环境中会面临以下问题:
Session 复制性能问题
当应用部署在多个 Tomcat 实例组成的集群环境时,每个 Tomcat 都会独立维护自己的 Session 存储
为了保证用户在不同实例间切换时 Session 不丢失,Tomcat 会通过组播(multicast)方式在各实例间复制 Session 数据
这种复制机制会带来显著的性能损耗:
每次 Session 变更都需要通过网络传输数据
集群规模越大,复制带来的网络开销呈指数级增长
在 Session 数据量较大时(如存储复杂对象),复制过程会消耗大量 CPU 和内存资源
Session 同步延迟问题
Tomcat 的 Session 复制采用异步方式,无法保证实时同步
典型场景示例:
用户登录后,请求被分发到 Tomcat A,Session 被创建
在复制完成前,用户的下一个请求被分发到 Tomcat B,此时 Tomcat B 尚未收到 Session 复制数据
导致用户需要重新登录,造成体验不一致
其他限制
不支持跨机房部署,因为组播通信通常无法跨越机房网络
当集群节点数量增加时,Session 复制会成为系统瓶颈
节点故障时可能导致部分 Session 数据丢失
解决方案
为了解决这些问题,常见的 Session 分离方案包括:
Session 粘滞(Sticky Session)
通过负载均衡器将同一用户的请求始终路由到同一 Tomcat 实例
缺点:无法实现真正的负载均衡,且节点故障时 Session 会丢失
集中式 Session 存储
将会话数据存储在 Redis、Memcached 等外部缓存中
所有 Tomcat 实例共享同一个 Session 存储
优点:彻底解决 Session 复制问题,支持水平扩展
无状态架构
完全放弃服务器端 Session,使用 Token 等机制管理会话状态
适合微服务架构和 RESTful API 场景
可以将登录后的Session信息
存入 Redis
中,这样多个Tomcat
服务器可以共享Session
信息。具体的整体架构图是:

分布式锁
一般锁是多线程 锁,但是在多个进程中,需要上锁的话,就需要分布式锁。
读写模式
旁路模式 (Cache Aside Pattern)
旁路缓存模式是分布式系统中应用最广泛的缓存+数据库读写策略之一,它通过将缓存置于数据库的"旁路"位置,实现了高性能与数据一致性的平衡。
核心实现原理
读操作流程:
应用程序首先查询缓存(如 Redis)
若缓存命中(cache hit),直接返回缓存数据
若缓存未命中(cache miss),则查询数据库
从数据库获取数据后,将结果写入缓存(通常设置 TTL)
最后返回数据给客户端
写操作流程:
应用程序先更新数据库
然后主动删除(而非更新)对应的缓存数据
确保后续读取时能加载最新数据
典型应用场景
用户个人资料系统:用户信息变化不频繁,但读取频繁
电商商品详情页:商品基础信息变更较少,但访问量大
新闻内容系统:新闻发布后基本不变,但需要快速读取
优势特点
简单可靠:实现逻辑清晰,容易理解和维护
减少写开销:只删除缓存而非更新,避免复杂的一致性问题
懒加载:只有被请求的数据才会被缓存,节省存储空间
潜在问题及解决方案
缓存穿透:
问题:频繁查询不存在的数据,导致每次都要查库
方案:缓存空对象或使用布隆过滤器
数据不一致窗口:
问题:数据库更新后到缓存删除前存在不一致
方案:设置合理的缓存过期时间,或引入消息队列确保删除
缓存击穿:
问题:热点 key 失效瞬间大量请求打到数据库
方案:使用互斥锁或永不过期策略
最佳实践建议
对于写多读少的场景要谨慎使用
设置合理的缓存过期时间(如 5-30 分钟)
考虑使用双删策略(更新数据库前后各删一次缓存)
监控缓存命中率,保持在 80%以上为佳
该模式因其简单高效的特点,成为大多数互联网公司的首选缓存方案,特别适合读多写少的业务场景。
代码逻辑上如下图:

当我们要更新数据的时候:先更新数据库,再删除缓存。

穿透模式
Read/Write Through Pattern
穿透读/穿透写
直接读/直接写
模式。
Read Through Pattern
Write Through Pattern
缓存模式
Write Behind Caching Pattern
只更新缓存
模式应用程序只更新缓存
,缓存通过异步的方式
将数据批量整合
后写入DB
。不能实时
同步数据,甚至宕机会丢数据
。
Redis 适用场景
缓存使用,减轻 DB 压力
DB 使用 用于临时存储数据
解决分布式场景下 Session 分离的问题
任务队列(秒杀,抢红包)乐观锁等等
应用排行榜
签到 bitmap
冷热数据交换
等等
缓存场景
Redis 常用于缓存系统,以提高数据读取速度并减轻数据库的负载。它可以存储经常访问的数据,如热门文章、用户信息、会话数据等。支持设置过期时间(TTL),自动清理过期的数据。
消息队列
Redis 的 List 结构和 Pub/Sub 功能可以用来实现消息队列,支持生产者和消费者模式。可以用于任务队列、异步处理等场景。
会话存储
Redis 被广泛用于会话管理,特别是在分布式系统中,可以共享会话数据。由于其高性能和持久化选项,可以确保会话数据的快速读取和安全存储。
排行榜/计数器
Redis 的 Sorted Set 结构可以轻松实现排行榜功能。适用于社交网络中的点赞数、游戏中的得分排名等场景。
实时分析
Redis 可以用于实时数据分析和统计,如网站的实时访问量统计、应用性能监控等。通过其快速的读写性能,可以实时更新和查询统计数据。
地理位置存储
Redis 的 Geospatial 功能可以存储和操作地理位置信息,适用于位置查询、距离计算等场景。可用于地图服务、物流跟踪等应用。
分布式锁
Redis 可以用于实现分布式锁,保证在分布式系统中的数据一致性。通过 SET NX 和 EXPIRE 命令,可以创建具有超时机制的锁。
发布/订阅(Pub/Sub)系统
Redis 提供了发布/订阅消息模式,适用于实时消息传递和通知系统。适用于聊天室、实时推送等场景。
数据结构存储
Redis 支持多种复杂数据结构,如字符串、哈希、列表、集合、有序集合等,可以满足多种数据存储需求。适用于需要快速访问和操作复杂数据结构的场景。
流处理
Redis 5.0 引入了 Stream 数据结构,用于处理实时数据流。适用于日志收集、事件溯源等场景。
版权声明: 本文为 InfoQ 作者【武子康】的原创文章。
原文链接:【http://xie.infoq.cn/article/36923ef8307a3695e5be1ed64】。文章转载请联系作者。
评论