了解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生成,感谢!

相关推荐
松涛和鸣4 小时前
72、IMX6ULL驱动实战:设备树(DTS/DTB)+ GPIO子系统+Platform总线
linux·服务器·arm开发·数据库·单片机
likangbinlxa4 小时前
【Oracle11g SQL详解】UPDATE 和 DELETE 操作的正确使用
数据库·sql
r i c k4 小时前
数据库系统学习笔记
数据库·笔记·学习
野犬寒鸦5 小时前
从零起步学习JVM || 第一章:类加载器与双亲委派机制模型详解
java·jvm·数据库·后端·学习
IvorySQL5 小时前
PostgreSQL 分区表的 ALTER TABLE 语句执行机制解析
数据库·postgresql·开源
·云扬·6 小时前
MySQL 8.0 Redo Log 归档与禁用实战指南
android·数据库·mysql
IT邦德6 小时前
Oracle 26ai DataGuard 搭建(RAC到单机)
数据库·oracle
惊讶的猫6 小时前
redis分片集群
数据库·redis·缓存·分片集群·海量数据存储·高并发写
不爱缺氧i6 小时前
完全卸载MariaDB
数据库·mariadb
期待のcode6 小时前
Redis的主从复制与集群
运维·服务器·redis