了解Redis


Redis介绍

1. 核心特性

  • 内存存储:数据主要保存在内存中,读写速度极快(微秒级响应)。
  • 持久化支持:可通过 RDB(快照)和 AOF(追加日志)机制将数据持久化到磁盘。
  • 丰富的数据结构 :不仅支持字符串(String),还支持:
    • 列表(List)
    • 集合(Set)
    • 有序集合(Sorted Set / ZSet)
    • 哈希(Hash)
    • 位图(Bitmap)、超日志(HyperLogLog)、地理空间(Geo)等
  • 高可用与扩展性
    • 主从复制(Replication)
    • 哨兵模式(Sentinel)实现自动故障转移
    • Redis Cluster 支持分布式部署和自动分片

2. 典型应用场景

  • 缓存:减轻数据库压力,加速热点数据访问。
  • 会话存储:如用户登录状态、购物车信息。
  • 排行榜/计数器:利用 Sorted Set 实现。
  • 消息队列:通过 List 或 Stream 实现轻量级队列。
  • 分布式锁 :使用 SET key value NX EX 实现。
  • 实时统计:如 UV/PV 统计(HyperLogLog)、在线用户数(Set)。

3. 关键命令示例

bash 复制代码
# 字符串
SET user:1001 "Alice"
GET user:1001

# 哈希
HSET user:1001 name "Alice" age 30
HGET user:1001 name

# 列表(左进右出)
LPUSH tasks "task1"
RPOP tasks

# 有序集合(带分数排序)
ZADD leaderboard 100 "player1"
ZREVRANGE leaderboard 0 9 WITHSCORES  # 获取前10名

# 设置过期时间
EXPIRE session:abc123 1800  # 30分钟过期

4. 性能与优化

  • 避免大 Key:单个 Value 过大会阻塞主线程。
  • 合理设置过期时间:防止内存无限增长。
  • 使用 Pipeline:批量发送命令减少网络往返。
  • 监控内存使用 :通过 INFO memory 查看。
  • 选择合适的数据结构:例如用 Hash 存储对象比多个 String 更省内存。

5. 安全与运维

  • 绑定 IP 和设置密码requirepass)。
  • 禁用危险命令 (如 FLUSHALL, KEYS *)通过 rename-command
  • 定期备份 RDB/AOF 文件
  • 监控工具 :Redis 自带 redis-cli --stat,或使用 Prometheus + Grafana。

6. 高级功能(Redis 6+)

  • ACL(访问控制列表):精细化权限管理。
  • Redis Streams:更强大的消息队列,支持消费者组。
  • 多线程 I/O(Redis 6+):提升网络读写性能(但命令执行仍是单线程)。
  • Redis Functions(Redis 7+):类似 Lua 脚本但更安全高效。

Redis 为什么这么快?

Redis 被广泛用作高性能缓存和实时数据存储系统,其"快"并非偶然,而是由多个关键设计决定的:

1. 基于内存操作

Redis 将所有数据存储在内存中,避免了磁盘 I/O 的延迟。内存访问速度通常在纳秒级,而传统磁盘(即使是 SSD)也在微秒到毫秒级,差距可达千倍以上。

2. 单线程模型 + I/O 多路复用

  • Redis 核心命令处理采用单线程(6.0 之前完全单线程,6.0+ 网络 I/O 多线程,命令执行仍单线。
  • 利用 epoll/kqueue 等 I/O 多路复用技术,一个线程可高效处理成千上万个并发连接,避免了线程切换和锁竞争的开销。
  • 单线程也意味着无需复杂的并发控制,逻辑简单且稳定。

3. 高效的数据结构

Redis 不仅是简单的 key-value 存储,它为不同场景提供了高度优化的底层数据结构:

  • 字符串(SDS:Simple Dynamic String)
  • 哈希表(渐进式 rehash 避免阻塞)
  • 跳表(用于 Sorted Set,支持 O(log N) 插入/查询)
  • 压缩列表(ziplist)、整数集合(intset)等内存紧凑结构

这些结构在时间和空间上都做了极致优化。

4. 避免上下文切换与锁竞争

由于核心逻辑单线程执行,Redis 几乎不需要加锁,极大减少了 CPU 在调度和同步上的浪费。

💡 总结:内存存储 + 单线程事件驱动 + 精巧数据结构 = 极致性能


Redis 集群架构演进:从主从复制到 Redis Cluster

随着业务规模的增长,Redis 的部署架构也经历了清晰的演进路径:主从复制 → 哨兵模式 → Redis Cluster。每一步都是为了解决前一阶段无法克服的瓶颈。

1. 主从复制(Replication)------解决单点故障,但能力有限

  • 核心机制:一个主节点(Master)负责读写,多个从节点(Slave/Replica)异步复制主节点数据,提供只读服务。
  • 优点
    • 数据冗余,避免单点宕机导致服务完全中断;
    • 可分担读请求压力(读写分离)。
  • 致命缺陷
    • 写操作仍集中在单个主节点,无法水平扩展写吞吐;
    • 所有节点存储全量数据,内存容量受限于单机上限;
    • 故障切换需人工干预,不具备自动恢复能力。

✅ 适用场景:小规模、对高可用要求不高、读多写少的系统。


2. 哨兵模式(Sentinel)------实现自动故障转移

  • 在主从基础上引入 Sentinel 集群(通常 3 节点以上),用于监控主从状态。
  • 核心功能
    • 监控(Monitoring):持续检查主从节点健康状态;
    • 自动故障转移(Failover):主节点宕机后,自动选举一个从节点晋升为主;
    • 通知(Notification):可触发告警或回调;
    • 配置提供者(Configuration Provider):客户端通过 Sentinel 获取当前主节点地址。
  • 改进点
    • 实现了 高可用自动化,减少运维负担。
  • 仍未解决的问题
    • 数据仍全量复制,无法突破单机内存限制;
    • 写性能无法横向扩展,依然是"单写多读"架构。

⚠️ 哨兵只是"高可用方案",不是"分布式方案"。


3. Redis Cluster ------ 真正的分布式解决方案

Redis 3.0(2015年)正式引入 Cluster 模式,标志着 Redis 迈入原生分布式时代。

核心设计思想:分片 + 去中心化 + 自动故障恢复
特性 说明
数据分片(Sharding) 将 key 空间划分为 16384 个槽(slot),每个主节点负责一部分槽。
无中心架构 所有节点对等通信,通过 Gossip 协议交换集群状态,无需哨兵或代理。
读写均可扩展 增加主节点即可提升存储容量和写吞吐;每个主可挂从节点提升读能力。
自动故障转移 主节点宕机后,其从节点自动选举晋升,全程无需外部干预。
客户端智能路由 客户端缓存 slot 到节点的映射,直接连接目标节点(支持 -MOVED 重定向)。
✅ 解决了什么?
  • 容量瓶颈:数据分散在多个节点,总内存 = 各节点之和;
  • 性能瓶颈:写请求可并行处理;
  • 运维复杂度:内置高可用,无需额外部署哨兵。

🌟 Cluster = 高可用 + 水平扩展 + 自治


Redis 缓存失效策略:过期 + 淘汰双保险

在高并发系统中,Redis 作为缓存层,不仅要"快",还要"智能"地管理数据生命周期。否则,要么缓存长期不更新导致数据陈旧,要么内存爆满引发服务崩溃。为此,Redis 提供了两套互补的失效机制:

过期策略(Expiration Policy) :控制"单个 key 何时失效"

内存淘汰策略(Eviction Policy):控制"内存不足时删哪些 key"


一、过期策略:让缓存自动"过期"

1. 如何设置过期时间?
bash 复制代码
# 设置 key 的生存时间(TTL)
SET user:1001 "Alice" EX 3600      # 1 小时后过期
EXPIRE session:abc 1800            # 给已有 key 设置 30 分钟过期
SETEX token:xyz 600 "abc123"       # 原子操作:设值 + 设过期
2. Redis 如何删除过期 key?------惰性删除 + 定期删除

Redis 并不会在 key 到期瞬间立即删除它,而是采用 组合策略 平衡性能与内存:

策略 说明 优点 缺点
惰性删除(Lazy Expiration) 只有当客户端访问某个 key 时,才检查是否过期,若过期则删除 CPU 友好,不浪费计算资源 过期 key 可能长期驻留内存
定期删除(Periodic Expiration) Redis 每秒运行 10 次(可配置),随机抽样部分设置了过期的 key,删除其中已过期的 主动释放内存,避免大量过期 key 积压 增加 CPU 开销

🔍 实际效果:既不会频繁扫描全量 key,也不会让过期数据无限堆积


二、内存淘汰策略:当 Redis "装不下" 时怎么办?

即使设置了过期时间,如果写入速度远大于过期/删除速度,或存在大量永不过期的 key,Redis 仍可能耗尽内存。此时,就需要 内存淘汰策略(maxmemory-policy) 来兜底。

1. 开启内存限制

redis.conf 中配置:

conf 复制代码
maxmemory 4gb          # 最大使用 4GB 内存
maxmemory-policy allkeys-lru  # 指定淘汰策略
2. 八种淘汰策略详解
策略 适用场景 行为说明
noeviction(默认) 不希望丢失任何数据 内存满后拒绝写入,返回错误(OOM)
allkeys-lru 通用推荐 从所有 key 中淘汰最近最少使用(LRU)的 key
volatile-lru 所有 key 都设置了过期时间 仅从有过期时间的 key中按 LRU 淘汰
allkeys-lfu(Redis 4.0+) 热点数据明显 淘汰最不经常使用(LFU)的 key(比 LRU 更精准)
volatile-lfu 同上,但只针对带过期的 key 仅淘汰带过期时间的 LFU key
allkeys-random 数据访问完全随机 随机淘汰任意 key
volatile-random 测试或特殊场景 随机淘汰带过期时间的 key
volatile-ttl 希望优先淘汰"快过期"的数据 优先淘汰剩余存活时间(TTL)最短的 key

💡 最佳实践建议

  • 如果 Redis 纯做缓存 (所有数据可重建)→ 用 allkeys-lruallkeys-lfu
  • 如果 Redis 混合存储 (部分 key 永久,部分缓存)→ 用 volatile-lru,并确保缓存 key 都设了过期时间
  • 生产环境切勿使用 noeviction,除非你明确接受写失败

三、常见陷阱与优化建议

  1. "缓存雪崩" :大量 key 同时过期 → 数据库瞬时压力暴增

    ✅ 解决方案:给过期时间加随机偏移(如 EX 3600 ± 300

  2. "缓存穿透" :查询不存在的数据,绕过缓存直击 DB

    ✅ 解决方案:对空结果也缓存(如 SET null_key "" EX 60),或用布隆过滤器

  3. 永不过期的 key 占满内存

    ✅ 解决方案:定期审计 key,或强制使用 volatile-* 策略 + 规范开发流程

  4. LRU/LFU 精度问题

    ✅ Redis 使用近似算法 (采样 LRU/LFU),可通过 maxmemory-samples 调整精度(默认 5)


学习资源推荐


本文最终由AI生成,感谢!

相关推荐
TG:@yunlaoda360 云老大2 小时前
如何了解华为云国际站代理商CDN主要有什么作用呢?
大数据·数据库·华为云
毕设十刻2 小时前
基于Vue的家教预约系统7fisz(程序 + 源码 + 数据库 + 调试部署 + 开发环境配置),配套论文文档字数达万字以上,文末可获取,系统界面展示置于文末
前端·数据库·vue.js
lightningyang2 小时前
渗透入门之SQL 注入(1)
数据库·sql·渗透·sql注入·天枢一体化虚拟仿真平台
阿坤带你走近大数据2 小时前
Oracle专家级数据库工程师的认知与经验
数据库·oracle
ZePingPingZe2 小时前
MySQL-InnoDB锁与事务
数据库·mysql
韩立学长3 小时前
Springboot森林资源检测管理系统xowdi7nq(程序、源码、数据库、调试部署方案及开发环境)系统界面展示及获取方式置于文档末尾,可供参考。
数据库·spring boot·后端
h7997103 小时前
高效统计mysql数据踩坑笔记
数据库·mysql
爱可生开源社区3 小时前
在数据库迁移中,如何让 AI 真正“可用、可信、可落地”?
数据库·sql·llm
猿小喵3 小时前
TDSQL-MySQL相对MySQL5.7版本主从复制性能优化
数据库·mysql·性能优化