写点什么

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

作者:武子康
  • 2025-07-12
    美国
  • 本文字数:3977 字

    阅读完需:约 13 分钟

大数据-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 命令实现简单事务


官方网站为:


http://redis.io/
复制代码

Redis 数据类型

Redis 支持五种核心数据类型,每种类型都有特定的使用场景和操作命令:

1. 字符串类型(String)

最基本的数据类型,可以存储字符串、整数或浮点数。最大能存储 512MB。典型应用场景:


  • 缓存简单数据

  • 计数器(如页面访问量)

  • 分布式锁

2. 散列类型(Hash)

适合存储对象,由字段-值对组成。每个哈希可以存储 4 亿多个字段-值对。典型应用场景:


  • 存储用户对象(用户名、年龄等信息)

  • 购物车数据

3. 列表类型(List)

有序的字符串集合,按照插入顺序排序。支持从两端插入/删除元素。典型应用场景:


  • 消息队列

  • 最新动态展示

  • 粉丝列表

4. 集合类型(Set)

无序的字符串集合,不允许重复元素。支持集合运算(交集、并集等)。典型应用场景:


  • 标签系统

  • 共同好友

  • 去重统计

5. 有序集合类型(Sorted Set)

每个元素都关联一个分数(score),用于排序。元素唯一,但分数可以重复。典型应用场景:


  • 排行榜

  • 带权重的队列

  • 范围查询

缓存场景

DB 缓存

DB 缓存是一种常见的缓存策略,主要用于减轻数据库服务器的压力。在常规的 Web 应用架构中,数据通常直接存储在关系型数据库中(如 MySQL、PostgreSQL 等),应用程序通过 SQL 查询直接与数据库交互。


随着业务增长和访问量上升,数据库可能成为系统瓶颈。当单日访问量达到上万级别时,数据库的读写压力会显著增加,可能导致查询响应变慢、连接池耗尽等问题。此时引入缓存机制可以有效缓解数据库压力。

典型应用场景

  1. 高频读取数据:如电商网站的商品详情、新闻站点的热门文章等

  2. 计算结果缓存:如统计报表、聚合查询结果

  3. 会话数据存储:用户登录状态、购物车信息等

解决方案

基础缓存方案

  • 对象缓存:将数据库查询结果以键值对形式存储在 Redis/Memcached 中

  • 查询缓存:缓存完整 SQL 语句及其结果

  • 延迟写:先更新缓存,异步批量写入数据库

进阶架构优化

  • 读写分离

  • 主库负责写操作,多个从库负责读操作

  • 通过 binlog 复制保持数据一致性

  • 适用于读写比例较高的场景(如 8:2)

  • 分库分表

  • 垂直分库:按业务领域拆分(如用户库、订单库)

  • 水平分表:单表数据按规则分散(如按用户 ID 哈希)

  • 需要处理分布式事务、跨库查询等问题

缓存策略选择

  1. Cache-Aside:先查缓存,未命中再查 DB

  2. Write-Through:同时更新缓存和 DB

  3. Write-Behind:先更新缓存,异步写入 DB

实施注意事项

  • 缓存失效策略(TTL 设置)

  • 缓存雪崩/穿透防护

  • 数据一致性保证

  • 监控缓存命中率


通过合理设计缓存策略,可以在保证数据一致性的前提下,将数据库 QPS 降低 50%-90%,显著提升系统性能。



数据库的文件是在硬盘中与内存交换。对于大量瞬时访问,会导致频繁IO无法工作

Session 分离

传统 Session 管理机制的问题

在传统的 Java Web 应用中,Session 是由 Tomcat 容器自行维护和管理的。这种机制在单机环境下运行良好,但在集群环境中会面临以下问题:


  1. Session 复制性能问题

  2. 当应用部署在多个 Tomcat 实例组成的集群环境时,每个 Tomcat 都会独立维护自己的 Session 存储

  3. 为了保证用户在不同实例间切换时 Session 不丢失,Tomcat 会通过组播(multicast)方式在各实例间复制 Session 数据

  4. 这种复制机制会带来显著的性能损耗:

  5. 每次 Session 变更都需要通过网络传输数据

  6. 集群规模越大,复制带来的网络开销呈指数级增长

  7. 在 Session 数据量较大时(如存储复杂对象),复制过程会消耗大量 CPU 和内存资源

  8. Session 同步延迟问题

  9. Tomcat 的 Session 复制采用异步方式,无法保证实时同步

  10. 典型场景示例:

  11. 用户登录后,请求被分发到 Tomcat A,Session 被创建

  12. 在复制完成前,用户的下一个请求被分发到 Tomcat B,此时 Tomcat B 尚未收到 Session 复制数据

  13. 导致用户需要重新登录,造成体验不一致

  14. 其他限制

  15. 不支持跨机房部署,因为组播通信通常无法跨越机房网络

  16. 当集群节点数量增加时,Session 复制会成为系统瓶颈

  17. 节点故障时可能导致部分 Session 数据丢失

解决方案

为了解决这些问题,常见的 Session 分离方案包括:


  1. Session 粘滞(Sticky Session)

  2. 通过负载均衡器将同一用户的请求始终路由到同一 Tomcat 实例

  3. 缺点:无法实现真正的负载均衡,且节点故障时 Session 会丢失

  4. 集中式 Session 存储

  5. 将会话数据存储在 Redis、Memcached 等外部缓存中

  6. 所有 Tomcat 实例共享同一个 Session 存储

  7. 优点:彻底解决 Session 复制问题,支持水平扩展

  8. 无状态架构

  9. 完全放弃服务器端 Session,使用 Token 等机制管理会话状态

  10. 适合微服务架构和 RESTful API 场景


可以将登录后的Session信息存入 Redis 中,这样多个Tomcat服务器可以共享Session信息。具体的整体架构图是:


分布式锁

一般锁是多线程 锁,但是在多个进程中,需要上锁的话,就需要分布式锁。

读写模式

旁路模式 (Cache Aside Pattern)

旁路缓存模式是分布式系统中应用最广泛的缓存+数据库读写策略之一,它通过将缓存置于数据库的"旁路"位置,实现了高性能与数据一致性的平衡。

核心实现原理

  1. 读操作流程

  2. 应用程序首先查询缓存(如 Redis)

  3. 若缓存命中(cache hit),直接返回缓存数据

  4. 若缓存未命中(cache miss),则查询数据库

  5. 从数据库获取数据后,将结果写入缓存(通常设置 TTL)

  6. 最后返回数据给客户端

  7. 写操作流程

  8. 应用程序先更新数据库

  9. 然后主动删除(而非更新)对应的缓存数据

  10. 确保后续读取时能加载最新数据

典型应用场景

  • 用户个人资料系统:用户信息变化不频繁,但读取频繁

  • 电商商品详情页:商品基础信息变更较少,但访问量大

  • 新闻内容系统:新闻发布后基本不变,但需要快速读取

优势特点

  1. 简单可靠:实现逻辑清晰,容易理解和维护

  2. 减少写开销:只删除缓存而非更新,避免复杂的一致性问题

  3. 懒加载:只有被请求的数据才会被缓存,节省存储空间

潜在问题及解决方案

  1. 缓存穿透

  2. 问题:频繁查询不存在的数据,导致每次都要查库

  3. 方案:缓存空对象或使用布隆过滤器

  4. 数据不一致窗口

  5. 问题:数据库更新后到缓存删除前存在不一致

  6. 方案:设置合理的缓存过期时间,或引入消息队列确保删除

  7. 缓存击穿

  8. 问题:热点 key 失效瞬间大量请求打到数据库

  9. 方案:使用互斥锁或永不过期策略

最佳实践建议

  • 对于写多读少的场景要谨慎使用

  • 设置合理的缓存过期时间(如 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 数据结构,用于处理实时数据流。适用于日志收集、事件溯源等场景。

发布于: 刚刚阅读数: 4
用户头像

武子康

关注

永远好奇 无限进步 2019-04-14 加入

Hi, I'm Zikang,好奇心驱动的探索者 | INTJ / INFJ 我热爱探索一切值得深究的事物。对技术、成长、效率、认知、人生有着持续的好奇心和行动力。 坚信「飞轮效应」,相信每一次微小的积累,终将带来深远的改变。

评论

发布
暂无评论
大数据-38 Redis 分布式缓存 详细介绍 缓存、读写、旁路、穿透模式_Java_武子康_InfoQ写作社区