Redis 核心技术解析

目录

一、Redis 的核心特点

二、Redis 常见数据类型

 三、持久化机制

1、RDB(Redis Database)

核心原理

优缺点

配置参数(redis.conf)

适用场景

2、AOF(Append Only File)

核心原理

优缺点

配置参数(redis.conf)

数据恢复流程

3、混合持久化(Hybrid Persistence)

核心原理

配置方式

4、两种持久化机制对比

四、Redis的过期键的删除策略 

1、惰性删除

2、定期删除

3、内存淘汰机制

五、redis事务 

1、事务相关命令

2、事务执行流程

3、事务的特性(与传统数据库的对比)

六、集群方案

1、主从复制(Master-Slave Replication)

1. 架构特点

2. 核心功能

3. 优缺点

4. 适用场景

2、哨兵模式(Sentinel)

1. 架构特点

2. 核心流程

3. 优缺点

4. 适用场景

3、集群模式(Cluster)

1. 架构特点(Redis Cluster)

2. 核心机制

3. 优缺点

4. 适用场景

4、三种模式对比表格

5、选择建议

七、redis缓存三兄弟

1、缓存穿透

问题描述

成因

解决方案

2、缓存击穿

问题描述

成因

解决方案

3、缓存雪崩

问题描述

成因

解决方案

4. 三兄弟对比总结


Redis(Remote Dictionary Server) 是一款基于内存的高性能键值对存储数据库,同时也是一个 数据结构服务器。它支持多种复杂的数据结构,并提供高读写性能、持久化、集群、事务等功能,被广泛应用于缓存、实时数据处理、消息队列、计数器、排行榜等场景。

一、Redis 的核心特点

  1. 基于内存(In-Memory)

    • 数据默认存储在内存中,读写速度极快(官方测试读速度可达 11 万次 / 秒,写速度可达 8 万次 / 秒)。
    • 缺点:内存空间有限,数据易失性(断电丢失),需通过持久化机制(RDB/AOF)保证数据可靠性。
  2. 丰富的数据结构
    Redis 支持多种数据结构,每种结构对应不同的应用场景:

    • 字符串(String):最简单的数据类型,用于存储单个值(如计数器、缓存用户信息)。
    • 哈希(Hash):键值对的集合,适合存储对象(如用户详情:user:1 {name: "Alice", age: 25})。
    • 列表(List):有序可重复的链表,支持两端插入 / 删除,用于消息队列(如任务队列)、最新列表(如朋友圈动态)。
    • 集合(Set):无序唯一的元素集合,用于去重(如统计用户唯一登录数)、交集 / 并集运算(如共同关注)。
    • 有序集合(Sorted Set):带分数的有序集合,用于排行榜(如按分数排序的用户排名)。
    • 其他:位图(Bitmap)、HyperLogLog(基数统计)、地理空间(Geospatial)等。
  3. 持久化机制

    • RDB(Redis Database):定时将内存数据快照写入磁盘,适合大规模数据的备份。
    • AOF(Append Only File):记录每一条写命令,重启时重新执行命令恢复数据,数据安全性更高。
    • 可同时开启 RDB 和 AOF,优先使用 AOF 恢复数据。
  4. 单线程与高性能

    • Redis 基于单线程模型处理请求(基于非阻塞 I/O 多路复用技术),避免了多线程的上下文切换开销,性能卓越。
    • 单线程意味着 Redis 自身不会出现线程安全问题,但需注意多个客户端并发访问时的竞争条件(可通过事务或分布式锁解决)。
  5. 原生支持集群(Cluster)

    • 可通过分片(Sharding)将数据分布到多个节点,支持动态扩缩容,解决单节点内存限制和高并发问题。
    • 集群模式下自动实现数据分片和故障转移,保证高可用性。
  6. 其他功能

    • 发布订阅(Pub/Sub):实现消息传递,用于实时通信(如实时聊天、通知系统)。
    • 事务(Transaction):支持简单的事务操作,确保命令序列的原子性执行。
    • Lua 脚本:支持在服务端执行 Lua 脚本,减少客户端与服务端的交互次数。
    • 过期键(TTL):可为键设置过期时间,自动清理无效数据(如缓存的有效期)。

二、Redis 常见数据类型

数据类型特点典型命令应用场景底层实现内存优化建议
字符串
(String)
- 最基础类型
- 二进制安全(可存储图片、JSON 等)
- 最大支持 512MB
SET key value
GET key
INCR key
MSET k1 v1 k2 v2
- 缓存(如用户信息)
- 计数器(点赞数、访问量)
- 分布式锁(SETNX
- 短字符串:embstr 编码(一次内存分配)
- 长字符串:raw 编码(两次内存分配)
- 避免大字符串(>10KB)
- 批量操作使用MSET/MGET
哈希
(Hash)
- 键值对集合(field→value)
- 类似 Java 的 HashMap
HSET hash field value
HGET hash field
HGETALL hash
HINCRBY
- 存储对象(如用户详情)
- 存储配置项(如应用配置)
- 小哈希:压缩列表(ziplist)
- 大哈希:哈希表(hashtable)
- 控制元素数量(默认 < 512)
- 值长度 < 64 字节(触发压缩列表)
列表
(List)
- 有序可重复
- 支持双向插入 / 删除
- 底层为双向链表
LPUSH list value1 value2
RPOP list
LRANGE list 0 -1
BLPOP
- 消息队列(FIFO/LIFO)
- 最新动态列表(如微博时间线)
- 小列表:压缩列表(ziplist)
- 大列表:快速列表(quicklist)
- 避免一次性获取全量数据(LRANGE 0 -1
- 使用BLPOP实现阻塞队列
集合
(Set)
- 无序唯一
- 支持交集 / 并集 / 差集运算
SADD set member1 member2
SMEMBERS set
SINTER set1 set2
SCARD
- 去重(如用户标签)
- 社交关系(共同好友)
- 抽奖系统(随机取元素)
- 整数集合(intset):全整数元素
- 哈希表(hashtable):含字符串元素
- 控制元素数量(>512 自动转为哈希表)
- 批量操作使用SUNIONSTORE
有序集合
(Sorted Set)
- 每个元素关联分数(score)
- 按分数排序(支持范围查询)
ZADD zset score1 member1 score2 member2
ZRANGE zset 0 -1 WITHSCORES
ZINCRBY
- 排行榜(如游戏积分)
- 时间线(按时间戳排序)
- 带权重的任务调度
- 跳表(skiplist)+ 哈希表
- 小数据:压缩列表(ziplist)
- 避免大范围查询(ZRANGE参数过大)
- 定期清理过期数据
位图
(Bitmap)
- 基于位操作的字符串
- 每个位存储 0/1
SETBIT key offset value
GETBIT key offset
BITCOUNT key
- 签到统计(每日 1 位)
- 用户活跃状态(亿级用户仅需 12.5MB)
- 布隆过滤器
- 基于字符串实现(本质是二进制数组)- 按位操作,避免整键读取
- 大位图可分段存储

补充说明

  1. 数据类型选择原则

    • 简单键值对:字符串(String)
    • 对象存储:哈希(Hash)
    • 有序列表:列表(List)或有序集合(Sorted Set)
    • 去重与集合运算:集合(Set)
    • 统计基数:HyperLogLog
    • 位操作:位图(Bitmap)
    • 地理位置:地理空间(Geospatial)
  2. 内存优化关键

    • 压缩列表(ziplist):当哈希、列表元素较少且值较小时自动触发,内存占用更低。
    • 批量操作:使用MSET/MGETHMSET/HMGET减少网络开销。
    • 过期策略:合理设置EXPIRE时间,避免冷数据长期占用内存。
  3. 性能注意事项

    • O (N) 命令:如KEYS *LRANGE list 0 -1SMEMBERS,可能阻塞主线程,生产环境慎用。
    • 大对象:单个键值超过 10KB 时需谨慎,可能导致内存碎片或网络传输瓶颈。
  4. 底层编码转换
    Redis 会根据数据量和类型自动转换编码(如小哈希从 ziplist 转为 hashtable),可通过OBJECT ENCODING key查看。

 三、持久化机制

Redis 提供了两种持久化机制:RDB(快照持久化) 和 AOF(日志追加持久化),用于将内存中的数据持久化到磁盘,避免因进程退出或服务器宕机导致数据丢失。此外,Redis 4.0 引入了 混合持久化 模式,结合两者优势。以下是详细解析:

1、RDB(Redis Database)
核心原理
  • 全量快照:将某一时刻的内存数据完整写入磁盘,生成 .rdb 文件。
  • 触发方式
    1. 自动触发:根据 redis.conf 中的配置规则(如 save 900 1 表示 900 秒内至少 1 次写操作则触发)。
    2. 手动触发
      • SAVE:阻塞主线程,直到快照完成(生产环境慎用)。
      • BGSAVE:fork 子进程执行快照,主线程继续处理请求(推荐方式)。
  • 执行流程
    1. 主线程 fork 子进程,子进程负责写入快照(copy-on-write 机制,不影响主线程读写)。
    2. 子进程将内存数据序列化到临时文件。
    3. 替换旧的 .rdb 文件,完成持久化。
优缺点
优点缺点
1. 文件体积小,恢复速度快(全量加载)。1. 无法实时持久化,可能丢失最近写入的数据。
2. 适合备份(如定时同步到远程服务器)。2. fork 子进程时可能占用大量内存和 CPU。
3. 跨版本兼容性好(不同 Redis 版本可读取)。3. 大内存实例 fork 时可能导致短暂阻塞。
配置参数(redis.conf)
# 自动触发规则(可配置多个条件,用空格分隔)
save 900 1        # 900秒内至少1次写操作
save 300 10       # 300秒内至少10次写操作
save 60 10000     # 60秒内至少10000次写操作

stop-writes-on-bgsave-error yes  # 快照失败时禁止写入(避免数据不一致)
rdbcompression yes               # 是否压缩数据(牺牲CPU换取空间)
rdbchecksum yes                   # 写入时校验数据(增加文件生成时间)
dbfilename dump.rdb               # 快照文件名
dir ./                            # 快照存储目录(需提前创建,权限可写)
适用场景
  • 对数据完整性要求不高,允许丢失最近几分钟数据。
  • 需定期备份(如每天一次),用于灾难恢复。
  • 主从复制场景(主节点通过 RDB 同步数据到从节点)。
2、AOF(Append Only File)
核心原理
  • 增量日志:将每个写命令(如 SET/HSET 等)按协议格式追加到 AOF 文件末尾,读命令不记录
  • 重写机制(AOF Rewrite)
    • 随着时间推移,AOF 文件会变庞大(如多次 INCR 同一个键),通过 BGREWRITEAOF 命令优化:
      • 子进程重新构建键值对的最小命令集合(如用最终的 SET 替代多次 INCR)。
      • 生成新的 AOF 文件,替换旧文件(不阻塞主线程)。
  • 触发重写方式
    1. 自动触发:根据 auto-aof-rewrite-percentage(默认 100%,即文件大小较上次重写后增长 100%)和 auto-aof-rewrite-min-size(默认 64MB,文件最小体积)。
    2. 手动触发:BGREWRITEAOF
优缺点
优点缺点
1. 数据安全性高(可配置每秒或实时刷盘)。1. 文件体积通常大于 RDB(记录所有写命令)。
2. 支持实时持久化(根据 fsync 策略)。2. 恢复速度较慢(需重放所有命令)。
3. 日志文件可读(便于排查问题)。3. 重写时可能消耗大量 CPU 和 I/O。
配置参数(redis.conf)
appendonly yes         # 启用 AOF(默认关闭)
appendfilename "appendonly.aof"  # AOF 文件名
appendfsync always     # 刷盘策略:
                        # always:每个写命令都刷盘(最慢,数据安全性最高)
                        # everysec:每秒刷盘(推荐,兼顾性能与安全)
                        # no:由操作系统决定(最快,风险高)
no-appendfsync-on-rewrite yes  # 重写时是否停止刷盘(避免阻塞)
auto-aof-rewrite-percentage 100 # 触发重写的文件增长百分比
auto-aof-rewrite-min-size 64mb  # 触发重写的最小文件大小
aof-load-truncated yes   # 加载时忽略损坏的日志(避免启动失败)
aof-use-rdb-preamble yes # 混合持久化时,在 AOF 开头添加 RDB 内容
数据恢复流程
  1. 读取 AOF 文件,解析并执行所有写命令,重建内存数据。
  2. 若 AOF 文件损坏,可通过 redis-check-aof --fix 工具修复。
3、混合持久化(Hybrid Persistence)
核心原理
  • Redis 4.0+ 新增:在 AOF 重写时,先将当前内存数据以 RDB 格式写入 AOF 文件开头,再追加增量的写命令。
  • 优势
    • 结合 RDB 的快速恢复能力(加载时先读 RDB 部分)和 AOF 的增量日志(仅重放最近命令)。
    • 减少 AOF 文件体积,提升恢复效率。
配置方式
aof-use-rdb-preamble yes  # 开启混合持久化(默认开启)
4、两种持久化机制对比
维度RDBAOF
数据安全低(可能丢失最后一次快照后的数据)高(取决于 fsync 策略)
文件体积小(压缩后)大(原始命令日志)
恢复速度快(全量加载)慢(重放所有命令)
性能影响fork 时可能阻塞主线程每秒刷盘几乎无阻塞,always 会降低写入性能
适用场景备份、主从同步、允许少量数据丢失金融交易、实时数据要求高的场景

四、Redis的过期键的删除策略 

Redis 的过期键删除策略采用 被动删除(惰性删除) 和 主动删除(定期删除) 结合的方式,并在内存不足时触发 内存淘汰机制。以下是具体策略的详细说明:

1、惰性删除
策略触发条件执行逻辑优点缺点
惰性删除客户端访问键时检查键是否过期:
- 过期则删除并返回 nil
- 未过期则正常处理请求
不主动消耗 CPU 资源可能导致过期键长期占用内存
适用场景读多写少、过期键易被访问
2、定期删除
策略触发条件执行逻辑优点缺点
定期删除周期性任务(默认每 100ms)1. 从每个数据库随机抽样少量键(默认 20 个)
2. 删除其中过期的键
3. 若过期键比例 > 25%,重复抽样(最多循环 ACTIVE_EXPIRE_CYCLE_LOOP 次,单次耗时 ≤ 25ms)
主动清理过期键,避免内存泄漏无法保证即时删除所有过期键
配置参数hz(默认 10,即每秒 10 次)增大 hz 提升清理频率增大 hz 会增加 CPU 消耗
3、内存淘汰机制

当内存使用达到 maxmemory 限制时,强制删除键(包括未过期键),优先淘汰过期键或符合策略的键:

策略作用范围淘汰逻辑
volatile-ttl仅设置过期时间的键优先删除剩余存活时间(TTL)最短的键
volatile-random仅设置过期时间的键随机删除设置过期时间的键
volatile-lru仅设置过期时间的键淘汰最近最少使用(LRU)的键
volatile-lfu仅设置过期时间的键淘汰最不常用(LFU)的键
allkeys-random所有键(无论是否过期)随机删除任意键
allkeys-lru所有键(无论是否过期)淘汰最近最少使用(LRU)的键
allkeys-lfu所有键(无论是否过期)淘汰最不常用(LFU)的键
noeviction(默认)所有键禁止删除任何键,写入操作报错

五、redis事务 

Redis 的事务(Transaction)提供了一种将多个命令组合执行的机制,确保多个操作按顺序执行,但不支持回滚(Rollback),主要用于简化批量操作和处理并发场景。以下是 Redis 事务的核心概念、命令、流程及特性的详细说明:

1、事务相关命令
命令作用
MULTI开启事务,标记后续命令进入队列(排队阶段),返回 OK
EXEC执行事务队列中的所有命令,返回各命令的结果列表;若中途监控键被修改,返回 nil
DISCARD放弃事务,清空队列并退出事务,返回 OK
WATCH key [key ...]监控一个或多个键,若事务执行前(EXEC 前)键被修改,则事务自动失败(EXEC 返回 nil)。
UNWATCH取消所有监控,用于主动放弃监控机制。
2、事务执行流程

2.1.开启事务

127.0.0.1:6379> MULTI
OK  # 进入事务模式,后续命令入队

2.2. 命令入队(Queue Commands)

  • 调用任意命令(如 SETGET 等),命令不会立即执行,而是加入事务队列,返回 QUEUED
  • 语法错误检查:命令入队时会检查语法,若有错误(如命令不存在),EXEC 时会拒绝执行整个事务。
    127.0.0.1:6379> SET key1 "value1"  # 入队成功,返回 QUEUED
    QUEUED
    127.0.0.1:6379> INVALID_COMMAND  # 语法错误,入队失败,标记事务为 discard
    (error) ERR unknown command `INVALID_COMMAND`
    

2.3. 执行事务(EXEC)或放弃事务(DISCARD)

  • 正常执行:若队列中所有命令语法正确且监控键未被修改,EXEC 按顺序执行所有命令,返回结果列表。
    127.0.0.1:6379> EXEC  # 执行事务
    1) OK  # SET key1 "value1" 的结果
    2) (error) ERR unknown command `INVALID_COMMAND`  # 语法错误的命令导致执行失败
    
  • 放弃事务:调用 DISCARD 会清空队列,退出事务模式。
    127.0.0.1:6379> DISCARD
    OK
    
3、事务的特性(与传统数据库的对比)
特性Redis 事务传统数据库事务
原子性(Atomicity)队列中的命令要么全部执行,要么全部不执行(仅在入队阶段有语法错误时);
执行阶段单命令失败不影响其他命令
整个事务要么全部成功,要么回滚。
一致性(Consistency)保证事务执行前后数据状态合法(依赖应用层逻辑)。事务执行前后数据满足完整性约束。
隔离性(Isolation)命令按入队顺序串行执行,无并发问题(单线程模型)。支持多种隔离级别(如读未提交、可重复读)。
持久性(Durability)取决于持久化策略(RDB/AOF),与事务无关。由数据库持久化机制保证(如 WAL 日志)。

4、乐观锁机制:WATCH 命令

作用

  • 监控键的变化,确保事务执行前键未被其他客户端修改,用于解决并发场景下的竞争条件(Race Condition)。

流程示例

  1. 监控键 balance
    127.0.0.1:6379> WATCH balance  # 监控账户余额
    OK
    
  2. 获取当前余额并开启事务
    127.0.0.1:6379> GET balance
    "100"
    127.0.0.1:6379> MULTI
    OK
    
  3. 模拟扣款操作(入队)
    127.0.0.1:6379> DECR balance  # 扣款 1 元,入队
    QUEUED
    
  4. 其他客户端修改 balance(模拟并发修改):
    127.0.0.1:6379> SET balance "90"  # 其他操作修改了余额
    OK
    
  5. 执行事务(失败)
    127.0.0.1:6379> EXEC  # 发现 balance 被修改,事务失败,返回 nil
    (nil)
    
  6. 处理失败(重试或放弃)
    127.0.0.1:6379> UNWATCH  # 取消监控,重新开始流程
    OK
    

5、事务的局限性

  1. 不支持回滚
    • 若命令在执行阶段失败(如类型错误),Redis 会跳过该命令,继续执行后续命令,不会回滚已执行的命令
      127.0.0.1:6379> MULTI
      OK
      127.0.0.1:6379> SET key "value"  # 入队成功
      QUEUED
      127.0.0.1:6379> LPUSH key "element"  # 类型错误(key 是字符串,非列表)
      QUEUED
      127.0.0.1:6379> EXEC
      1) OK  # SET 成功
      2) (error) WRONGTYPE Operation against a key holding the wrong kind of value  # LPUSH 失败
      
  2. 无法解决所有并发问题
    • WATCH 仅能监控键是否被修改,无法处理复杂的业务逻辑冲突(如金额计算错误),需应用层处理。
  3. 性能限制
    • 事务本质是批量执行命令,若包含大量操作,可能阻塞 Redis 主线程,需合理控制事务规模。

5、适用场景

  1. 批量操作:简化多个命令的顺序执行(如先查询再更新)。
  2. 乐观锁场景:通过 WATCH 防止并发修改(如库存扣减、账户余额调整)。
  3. 简单事务逻辑:无需回滚的场景(如缓存更新、计数器批量操作)。

六、集群方案

Redis 提供了多种集群方式以满足不同的业务需求,主要包括 主从复制(Master-Slave Replication)哨兵模式(Sentinel)和 集群模式(Cluster)。以下是各模式的详细对比和说明:

1、主从复制(Master-Slave Replication)
1. 架构特点
  • 单主多从:一个主节点(Master)负责写入,多个从节点(Slave)复制主节点数据,从节点支持读操作。
  • 数据同步:主节点通过 RDB 快照和增量日志(AOF 重写)向从节点同步数据。
  • 读写分离:读请求由从节点处理,写请求集中在主节点,提升读性能。
2. 核心功能
  • 数据备份:从节点作为主节点的副本,用于容灾备份。
  • 扩展读能力:通过增加从节点数量分担读压力。
  • 手动故障转移:主节点故障时需手动将从节点提升为新主节点。
3. 优缺点
优点缺点
- 配置简单,易于实现- 主节点单点故障,需手动切换
- 支持读写分离- 无法自动恢复,存在服务中断风险
- 适合读多写少场景- 从节点数据可能存在延迟(异步复制)
4. 适用场景
  • 简单数据备份和读写分离场景(如缓存层读扩展)。
  • 对高可用性要求不高的业务(如非核心系统)。
2、哨兵模式(Sentinel)
1. 架构特点
  • 主从 + 哨兵节点:在主从复制基础上,引入独立的哨兵节点(Sentinel)组成集群。
  • 自动监控:哨兵节点定期监控主从节点状态,检测主节点故障。
  • 自动故障转移:主节点故障时,哨兵自动选举从节点为新主节点,并重新配置其他从节点。
2. 核心流程
  1. 监控:哨兵节点通过 PING 命令检查主从节点存活状态。
  2. 选举:当主节点被多数哨兵认定为下线(ODOWN),触发选举机制,选择最优从节点(如复制偏移量最大、优先级最高)。
  3. 故障转移:将选中的从节点提升为新主节点,其他从节点指向新主节点,通知客户端更新连接。
3. 优缺点
优点缺点
- 自动故障转移,高可用- 不支持数据分片,单机存储限制
- 多哨兵节点避免单点故障- 主节点写压力大,无法横向扩展数据量
- 兼容主从复制的读写分离- 故障转移期间存在短暂服务不可用
4. 适用场景
  • 对高可用性要求较高的场景(如生产环境缓存)。
  • 数据量较小、写请求不密集的业务(如中小型应用)。
3、集群模式(Cluster)
1. 架构特点(Redis Cluster)
  • 分布式架构:节点分为 主节点(Master) 和 从节点(Slave),主节点负责数据读写,从节点作为备份。
  • 数据分片(Sharding):通过 哈希槽(Hash Slot) 机制将数据分散到不同主节点。Redis 集群共有 16384 个哈希槽,每个主节点负责部分槽位。
  • 节点间通信:节点通过 Gossip 协议 交换集群状态,自动发现和维护节点关系。
2. 核心机制
  • 哈希槽分配
    数据键通过 CRC16(key) % 16384 计算槽位,映射到对应主节点。例如:
    槽位 0-5460 → 节点 A
    槽位 5461-10922 → 节点 B
    槽位 10923-16383 → 节点 C
    
  • 自动故障转移:与哨兵模式类似,主节点故障时,从节点自动提升为新主节点,并重新分配槽位。
  • 横向扩展:可通过添加节点组(主从对)动态调整槽位分布,无需停机。
3. 优缺点
优点缺点
- 支持数据分片,突破单机存储限制- 配置和管理复杂(需手动分配槽位)
- 高可用性(主从 + 自动故障转移)- 客户端需支持集群模式(如 Redis-Py Cluster)
- 读写性能可线性扩展- 跨节点操作需通过路由,存在延迟
- 适合大数据量和高并发场景- 不支持多键事务(仅支持单槽操作)
4. 适用场景
  • 数据量较大(GB 级以上)或访问流量高的场景(如大型电商、社交平台)。
  • 需要水平扩展读写能力的业务(如实时统计、分布式缓存)。
4、三种模式对比表格
维度主从复制哨兵模式集群模式
高可用性手动切换,低自动故障转移,高自动故障转移,高
数据分片不支持不支持支持(16384 哈希槽)
读写扩展读可扩展(从节点)读可扩展(从节点)读写均可扩展(节点)
单机瓶颈主节点存在主节点存在无(数据分散存储)
部署复杂度简单中等(需配置哨兵)复杂(槽位管理)
典型场景备份、读写分离高可用中小规模数据大规模数据 / 高并发
Redis 版本2.0+2.8+3.0+
5、选择建议
  1. 小规模场景
    • 若仅需备份和读写分离,选 主从复制
    • 若需自动故障转移,选 哨兵模式
  2. 大规模场景
    • 数据量超过单机限制或需高并发,选 集群模式
  3. 特殊需求
    • 需多数据中心容灾,可结合 主从复制 + 异步复制
    • 需强一致性,谨慎使用(Redis 基于异步复制,存在短暂数据丢失可能)。

七、redis缓存三兄弟

在 Redis 缓存体系中,“缓存三兄弟” 通常指的是缓存穿透缓存击穿缓存雪崩,这三个是缓存场景中常见的典型问题,会严重影响系统性能甚至导致服务崩溃。以下是对它们的详细解析:

1、缓存穿透
问题描述
  • 场景:客户端请求不存在于缓存和数据库中的数据,导致请求直接穿透缓存层,每次都访问数据库。
  • 危害:大量无效请求会压垮数据库,甚至引发DDoS 攻击
成因
  • 恶意攻击:攻击者故意请求不存在的键(如随机字符串)。
  • 业务逻辑漏洞:如用户输入非法参数,查询不存在的数据。
解决方案
  1. 布隆过滤器(Bloom Filter)

    • 原理:在请求进入数据库前,用布隆过滤器快速判断数据是否存在。若不存在,直接拒绝请求,避免穿透到数据库。
    • 适用场景:数据基数大、更新频率低的场景(布隆过滤器更新成本较高)。
  2. 空值缓存

    • 原理:当查询结果为 null 时,仍将空值存入缓存(设置较短过期时间,如 5 分钟),避免相同请求反复查询数据库。
    • 注意:需设置合理过期时间,防止缓存大量无效数据。
  3. 参数校验

    • 对请求参数进行合法性校验(如 ID 格式、范围限制),提前拦截无效请求。
2、缓存击穿
问题描述
  • 场景热点数据的缓存过期瞬间,大量请求同时访问数据库,导致数据库压力激增。
  • 关键词单个热点键、缓存过期、并发请求
成因
  • 热点数据(如秒杀商品、热门新闻)的缓存设置了固定过期时间,到期时大量用户请求同时到达。
解决方案
  1. 热点数据永不过期

    • 不设置过期时间,通过其他机制(如异步线程)主动更新缓存(需注意数据一致性)。
  2. 加互斥锁(Mutex)

    • 原理:当缓存失效时,仅允许单个请求访问数据库并重建缓存,其他请求等待锁释放后从缓存获取数据。
    • 实现方式
      • 使用 Redis 的 SET NX 命令实现分布式锁(如 set lock_key unique_value nx px 10000)。
      • 注意设置锁的过期时间,避免死锁。
  3. 提前更新缓存

    • 在缓存过期前(如剩余 10% 时间),异步提前刷新缓存,避免到期时被动重建。
3、缓存雪崩
问题描述
  • 场景大量缓存键同时过期Redis 服务宕机,导致大量请求直接涌入数据库,造成数据库负载过高甚至崩溃。
  • 关键词大量键过期、缓存不可用、请求激增
成因
  • 批量缓存设置了相同或相近的过期时间,到期时集体失效。
  • Redis 集群故障(如主从切换、节点宕机),导致缓存服务整体不可用。
解决方案
  1. 分散过期时间

    • 在设置缓存过期时间时,添加随机时间偏移(如 TTL = 3600 + random(600)),避免大量键同时过期。
  2. 提升缓存高可用性

    • 采用 Redis 集群(Cluster)或主从复制(Master-Slave)架构,结合 Sentinel 实现自动故障转移,减少单点故障影响。
  3. 熔断降级

    • 通过熔断器(如 Hystrix、Resilience4j)监控数据库负载,当压力超过阈值时,直接返回预设的默认值或提示信息,保护数据库。
  4. 限流

    • 通过限流组件(如 Guava RateLimiter、Redis 限流)限制单位时间内的请求量,避免突发流量压垮系统。
  5. 二级缓存

    • 使用本地缓存(如 Caffeine、Ehcache)作为一级缓存,Redis 作为二级缓存,降低对 Redis 的依赖。
4. 三兄弟对比总结
问题核心原因典型场景解决方案核心思路
缓存穿透请求不存在的数据恶意攻击、非法参数查询过滤无效请求、缓存空值
缓存击穿单个热点键过期,并发请求热点商品秒杀、突发流量避免并发重建、延长热点键存活
缓存雪崩大量键过期或缓存服务不可用批量缓存到期、Redis 宕机分散过期时间、增强系统容错
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值