redis核心原理与实战应用
Redis 常被用作缓存、分布式锁、排行榜、计数器和会话存储。它的核心优势不是“能存数据”这么简单,而是用内存访问、丰富数据结构、持久化和高可用机制,支撑高并发场景下的读写性能与系统稳定性。
这篇文章按实际使用路径整理 Redis:先看基础能力,再看高可用与缓存问题,最后整理一致性、性能优化和典型场景。
一、Redis 基础概念
Section titled “一、Redis 基础概念”数据类型支持
Section titled “数据类型支持”Redis 支持多种常用数据结构:
- String:适合缓存简单值、计数器、分布式锁标记。
- Hash:适合存储对象字段,例如用户信息。
- List:适合队列、消息列表、时间线等场景。
- Set:适合去重、集合交并差。
- Sorted Set(ZSet):适合排行榜、权重排序、延迟队列。
这些结构让 Redis 不只是一个 Key-Value 缓存,而是可以承接一部分高频读写业务逻辑。
Redis 主要有两种持久化方式:RDB 和 AOF。
RDB(快照)
- 定期生成内存快照,例如通过
bgsave命令。 - 优点:文件体积较小,数据恢复速度快。
- 缺点:如果 Redis 异常退出,可能丢失最后一次快照之后的数据。
AOF(追加日志)
- 记录每一次写操作命令,例如
SET key value。 - 优点:数据安全性更高,可以配置更高频率的落盘。
- 缺点:文件体积更大,恢复速度通常慢于 RDB。
实际生产中常见策略是 RDB + AOF 组合使用:RDB 用于快速恢复,AOF 用于降低数据丢失风险。
二、主从同步与高可用
Section titled “二、主从同步与高可用”主从同步方式
Section titled “主从同步方式”Redis 主从同步分为全量同步和增量同步。
全量同步
通常发生在从节点初次连接主节点,或断线时间过长无法增量追赶时:
- 主节点生成 RDB 文件。
- 主节点把 RDB 文件发送给从节点。
- 从节点清空旧数据并加载 RDB。
- 主节点继续把同步期间缓冲区中的写操作发送给从节点。
增量同步
当从节点短暂断线后重新连接,可以通过 psync 根据复制偏移量(offset)同步缺失的写操作,避免重新做一次全量同步。
Redis 常见高可用方案主要有两类:
- 哨兵模式(Sentinel):监控主从节点状态,在主节点故障时自动完成故障转移。
- 集群模式(Cluster):通过分片存储数据,提升容量上限,并支持水平扩展。
哨兵更偏向主从高可用,集群更偏向容量扩展和分片治理。
三、缓存问题与解决方案
Section titled “三、缓存问题与解决方案”缓存击穿指的是一个热点 Key 在高并发访问时突然过期,大量请求同时打到数据库。
常见解决方案:
- 热点 Key 不设置过期时间,通过后台任务主动刷新。
- 互斥锁或分布式锁,只允许一个请求回源重建缓存。
- 逻辑过期,缓存中保存过期时间,由后台异步刷新数据。
缓存穿透指的是大量请求访问不存在的数据,缓存无法命中,请求直接落到数据库。
常见解决方案:
- 布隆过滤器:在请求进入缓存和数据库之前过滤明显不存在的 Key。
- 缓存空对象:对不存在的数据短时间缓存空值,避免重复打到数据库。
- 参数校验:拦截非法 ID、异常参数和明显无效请求。
缓存雪崩指的是大量 Key 在同一时间过期,导致请求集中打到数据库。
常见解决方案:
- 随机过期时间,避免大量 Key 同时失效。
- 限流降级,在数据库压力过高时保护核心服务。
- 多级缓存或集群部署,减少单点缓存失效带来的冲击。
四、数据一致性与 Redis-MySQL 同步
Section titled “四、数据一致性与 Redis-MySQL 同步”双写一致性方案
Section titled “双写一致性方案”业务中常见的数据源组合是 MySQL 存储主数据,Redis 作为缓存。这里的核心问题是:数据库更新后,缓存如何保持一致。
常见方案:
- 先写 MySQL,再更新 Redis:逻辑直接,但并发下可能出现旧值覆盖新值。
- 先写 MySQL,再删除 Redis:更常见,后续请求回源数据库并重建缓存。
- 延迟双删:写库后删除缓存,短暂延迟后再次删除,降低并发读写导致的脏缓存概率。
- 最终一致性:通过消息队列或 Canal 监听 MySQL Binlog,把数据变更异步同步到 Redis。
业务场景适配
Section titled “业务场景适配”- 对实时一致性要求很高的场景,需要更严格的事务或强一致方案。
- 对短暂延迟可接受的场景,通常使用缓存删除、消息队列、Binlog 同步等最终一致性方案。
缓存一致性没有绝对通用答案,重点是结合业务对“延迟、正确性、复杂度”的要求做取舍。
五、Redis 性能优化
Section titled “五、Redis 性能优化”Redis 提供 slowlog 用于排查慢查询。常见优化方向:
- 避免
KEYS *、SORT、大范围SUNION等高复杂度命令。 - 对批量操作使用 Pipeline,减少网络往返。
- 控制单次命令处理的数据规模,避免阻塞主线程。
内存淘汰策略
Section titled “内存淘汰策略”当内存达到 maxmemory 限制时,Redis 会根据配置的淘汰策略处理 Key。
常见策略:
- noeviction:内存不足时拒绝写入。
- volatile-lru:只在设置了过期时间的 Key 中淘汰最近最少使用的 Key。
- volatile-lfu:只在设置了过期时间的 Key 中淘汰最近最不常用的 Key。
- allkeys-lru:在所有 Key 中淘汰最近最少使用的 Key。
- allkeys-lfu:在所有 Key 中淘汰最近最不常用的 Key。
- allkeys-random:在所有 Key 中随机淘汰。
缓存场景通常更常见 allkeys-lru 或 allkeys-lfu,但具体选择要看访问分布和业务容忍度。
BigKey 与 HotKey
Section titled “BigKey 与 HotKey”BigKey 指单个 Key 占用过大内存或包含过多元素,会导致网络传输、删除、迁移和持久化变慢。
HotKey 指少数 Key 被高频访问,容易造成单点压力。
优化方向:
- 拆分过大的 Hash、List、Set、ZSet。
- 避免一次性读取或删除大 Key。
- 对热点数据做本地缓存、多副本缓存或请求合并。
六、线程模型与内存管理
Section titled “六、线程模型与内存管理”Redis 的命令执行主要是单线程模型,这让它避免了大量锁竞争,命令执行顺序也更容易理解。
Redis 6.0 之后引入多线程处理网络 I/O,但命令执行本身仍然保持单线程语义。因此,慢命令、大 Key 操作、复杂聚合仍然可能阻塞 Redis。
过期键删除策略
Section titled “过期键删除策略”Redis 对过期 Key 主要使用两种删除策略:
惰性删除
- 获取 Key 时检查是否过期,过期则删除。
- 优点:不主动消耗额外资源。
- 缺点:如果过期 Key 长时间不被访问,可能继续占用内存。
定期删除
- Redis 定期随机抽样部分 Key,删除其中已经过期的 Key。
- 优点:可以主动清理过期数据。
- 缺点:不保证所有过期 Key 都会立刻被删除。
Redis 默认使用 惰性删除 + 定期删除 的组合策略。
七、Redis 变慢的排查方向
Section titled “七、Redis 变慢的排查方向”Redis 变慢时,可以从以下方向排查:
- 检查内存是否耗尽,是否发生 Swap,例如使用
free -m。 - 检查磁盘 I/O,尤其是 AOF 写入和重写期间。
- 使用 SSD 替代传统磁盘,降低持久化带来的 I/O 压力。
- 排查是否使用了
KEYS、SORT、SUNION等高复杂度命令。 - 检查是否存在大批量读取、大批量删除或大集合遍历。
- 对批量请求使用 Pipeline,减少网络延迟。
AOF 重写阻塞
Section titled “AOF 重写阻塞”AOF 重写期间可能与 fsync 竞争磁盘资源。可以根据场景配置:
no-appendfsync-on-rewrite yes这个配置可以降低 AOF 重写期间的写入阻塞风险,但也会增加极端情况下的数据丢失窗口,需要结合业务容忍度评估。
缓存雪崩或击穿
Section titled “缓存雪崩或击穿”如果数据库和 Redis 同时出现压力波动,需要排查是否存在:
- 大量 Key 同时过期。
- 热点 Key 突然失效。
- 缓存重建逻辑没有互斥保护。
八、Redis vs Memcached
Section titled “八、Redis vs Memcached”| 特性 | Redis | Memcached |
|---|---|---|
| 数据类型 | String、Hash、List、Set、ZSet 等 | 主要支持简单 Key-Value |
| 持久化 | 支持 RDB、AOF | 不支持持久化 |
| 内存回收 | 支持多种淘汰策略 | 支持 LRU 等缓存淘汰机制 |
| 原子操作 | 支持较丰富的原子操作 | 支持有限原子操作 |
| 线程模型 | 命令执行以单线程为主,Redis 6.0 后支持 I/O 多线程 | 多线程网络模型 |
| 场景适用 | 复杂缓存、计数、排行榜、分布式锁 | 简单缓存、高吞吐 Key-Value |
简单说:如果只是做非常简单的缓存,Memcached 也可以胜任;如果需要更丰富的数据结构、持久化、高可用和分布式能力,Redis 更适合。
九、典型场景应用
Section titled “九、典型场景应用”Redis 常见业务场景包括:
- 缓存:存储热点数据,减少数据库压力。
- 会话保持:存储用户 Session 或登录态。
- 排行榜:通过 ZSet 实现 Top N 榜单。
- 限流降级:通过计数器、滑动窗口或令牌桶实现接口限流。
- 分布式锁:使用
SET key value NX PX等命令实现基础锁能力。 - 延迟队列:通过 ZSet 分数存储执行时间,实现定时任务调度。
Redis 的核心价值在于 高性能访问、灵活数据结构、持久化能力和分布式支持。
实际使用 Redis 时,需要重点关注四件事:
- 数据结构是否选对。
- 缓存异常场景是否有兜底方案。
- Redis 与数据库之间是否能接受最终一致性。
- 是否避免了慢命令、BigKey、HotKey 和集中过期。
理解这些核心机制后,Redis 就不只是一个缓存组件,而是高并发系统中非常重要的性能与稳定性基础设施。