2. Redis 基础回顾:核心数据结构与运行机制
在深入削峰与缓存一致性实战之前,必须牢固掌握 Redis 的五大基础数据结构、单线程事件驱动模型以及持久化机制。这些是理解 Redis 高性能、原子性操作以及数据安全特性的基石。
2.1 五大基础数据结构
Redis 是一个键值对数据库,但它的值并不仅仅是简单的字符串。它支持多种数据结构,每种结构都针对特定场景进行了优化。下表总结了五种最常用的数据结构及其核心特性:
| 数据结构 | 内部编码 | 核心命令示例 | 时间复杂度 | 典型应用场景 |
|---|---|---|---|---|
| String | int, embstr, raw | SET, GET, INCR, DECR, MSET | O(1) | 计数器、分布式锁、Session 共享、缓存对象 |
| Hash | ziplist, hashtable | HSET, HGET, HGETALL, HINCRBY | O(1) 平均 | 存储对象(如用户信息、商品详情)、购物车 |
| List | quicklist | LPUSH, RPUSH, LPOP, BRPOP, LRANGE | O(1) 头尾操作 | 消息队列、时间线(Timeline)、最新列表 |
| Set | intset, hashtable | SADD, SREM, SMEMBERS, SINTER, SUNION | O(1) 增删查 | 标签系统、共同好友、抽奖、去重 |
| ZSet | ziplist, skiplist | ZADD, ZRANGE, ZREVRANGE, ZRANK, ZINCRBY | O(log N) | 排行榜、延时队列、优先级队列、限流滑动窗口 |
实战提示: 在削峰场景中,List 常用于构建异步队列(LPUSH + BRPOP),ZSet 则用于实现基于时间戳的滑动窗口限流或延时任务调度。选择合适的数据结构能显著降低系统复杂度。
2.2 Redis 单线程模型
Redis 的核心处理逻辑是单线程的,这意味着它使用一个主线程(Main Reactor)来处理所有客户端的命令请求。这个模型是 Redis 高性能的关键之一。
- 核心机制: 基于 I/O 多路复用(如 epoll/kqueue)和事件循环(Event Loop)。主线程在一个循环中同时监听多个 Socket 上的可读/可写事件。
- 处理流程: 当有新的连接请求或命令请求到达时,事件处理器将其放入队列,然后单线程依次从队列中取出事件并执行对应的回调函数。
- 优势:
- 无锁竞争: 避免了多线程编程中常见的锁竞争、上下文切换和死锁问题,数据访问天然线程安全。
- 可预测性: 执行顺序确定,性能模型简单,易于理解和优化。
- 高性能: 纯内存操作 + 非阻塞 I/O + 单线程避免了多线程开销,使得 Redis 在绝大多数场景下都能达到极高的吞吐量(通常可达 10万+ QPS)。
- 注意事项: 单线程意味着所有命令都是串行执行的。如果某个命令执行时间过长(如
KEYS *、SMEMBERS大集合、HGETALL大哈希),会阻塞后续所有命令,导致 Redis 响应延迟飙升。这是生产环境必须避免的“慢查询”问题。
避坑指南: 严禁在生产环境使用
KEYS * 命令。应使用 SCAN 系列命令进行渐进式遍历。对于大 Key(Big Key),应通过拆分、异步删除(UNLINK)等方式处理,避免阻塞主线程。
2.3 Redis 持久化机制
Redis 是内存数据库,但为了防止数据丢失,它提供了两种主要的持久化方式:RDB(快照)和 AOF(追加文件)。理解它们的原理和差异,对于设计高可用缓存架构至关重要。
2.3.1 RDB(Redis Database)
- 原理: 在指定的时间间隔内,将内存中的数据集快照(Snapshot)写入磁盘的二进制文件(默认
dump.rdb)。 - 触发方式:
- 手动:
SAVE(同步阻塞)、BGSAVE(异步,fork 子进程执行)。 - 自动: 根据配置文件中的
save指令(如save 900 1表示 900 秒内至少 1 个 key 变化则触发)。
- 手动:
- 优点: 文件紧凑,适合备份和灾难恢复;恢复速度比 AOF 快。
- 缺点: 可能会丢失最后一次快照之后的所有数据;
fork子进程时,如果数据集很大,可能会导致服务短暂停顿。
2.3.2 AOF(Append Only File)
- 原理: 以日志的形式记录每个写操作(命令),Redis 重启时会重新执行这些命令来恢复数据。
- 刷盘策略(appendfsync):
- always: 每次写命令都同步到磁盘,最安全,但性能最慢。
- everysec: 每秒同步一次,兼顾性能与安全(推荐,最多丢失 1 秒数据)。
- no: 由操作系统决定何时同步,性能最快,但数据安全性最差。
- 优点: 数据安全性高(最多丢失 1 秒数据);AOF 文件可读,便于误操作修复。
- 缺点: 相同数据集下,AOF 文件体积通常比 RDB 大;恢复速度比 RDB 慢。
生产建议: 通常建议同时开启 RDB 和 AOF。RDB 用于快速恢复和备份,AOF(everysec)用于保证数据安全。在 Redis 重启时,会优先使用 AOF 文件来恢复数据,因为它通常更完整。