持久化与内存管理¶
Redis 主要在内存中处理数据,进程退出后内存内容会消失。持久化负责把可恢复的数据写到磁盘;复制负责在别的实例保存副本;高可用负责故障后恢复服务。这三者互相配合,不能互相替代。
RDB:给数据拍一张快照¶
RDB 保存一个时间点的数据集,适合备份、迁移和启动加载。两次快照之间的数据没有包含在旧快照里,因此只靠旧 RDB 恢复时会丢失后面的修改。
BGSAVE 用后台子进程生成快照,父进程继续处理请求;但 fork 以及写时复制仍会带来暂停或内存压力。SAVE 会同步执行快照并阻塞服务,不应作为繁忙生产环境的随手检查命令。
配置例子:save 900 1 表示满足“900 秒内至少 1 次修改”等条件时触发快照,不是每写一条就落盘。
AOF:保存能够重建数据的写操作记录¶
AOF 通过记录写入操作来恢复数据。它会增长,因此需要重写,将历史操作整理成能表达当前数据的更紧凑形式。重写是存储整理,不是清除业务数据。
appendfsync |
行为 | 取舍 |
|---|---|---|
always |
每次写入按策略同步到磁盘 | 更强调持久性,磁盘成本和延迟更高 |
everysec |
通常每秒执行同步 | 常见折中;异常时通常存在约 1 秒写入丢失窗口,不是所有故障的硬保证 |
no |
由操作系统决定刷盘时机 | 延迟可能较低,但丢失窗口更不可控 |
Redis 7+ 使用多文件 AOF,包含 manifest、基础文件和增量文件等。备份与恢复应保存一致的完整集合,不能以为永远只有一个 appendonly.aof。同时启用 RDB 与 AOF 时,正常启动会优先使用 AOF 恢复。官方持久化说明
选哪一种¶
普通可重建缓存可以按回源能力决定是否持久化;关闭持久化后,重启时冷缓存可能压垮数据库。会话、队列或其他难以重建的数据,需要更明确的恢复目标、持久化和备份安排。
我会先确认允许丢多少数据(RPO),再确认能停多久(RTO),最后决定策略。AOF、RDB 和副本都可能同步保存误删除结果;恢复历史数据依赖独立备份及恢复演练。
TTL 到期与内存淘汰是两回事¶
TTL 到期: 到了应用约定的时间,key 应该失效。Redis 会在访问时检查,也会主动抽样清理,不是每个 key 都创建一个独立定时器。
内存淘汰: 到达 maxmemory 后,为了继续处理需要内存的请求,按策略选择 key 移除。它可能在 TTL 尚未到期时发生。
所以 TTL 不是“这条数据至少能保存这么久”的保证。用 Redis 保存重要状态时,不能让它随意被缓存淘汰策略删除。
maxmemory-policy 决定内存满了怎么做¶
| 策略 | 含义 | 适合的考虑方向 |
|---|---|---|
noeviction |
不自动淘汰;需要额外内存的写命令可能报错 | 不允许自动丢 key 的状态数据,需要容量告警 |
allkeys-lru |
从所有 key 中近似挑选最近较少使用的 | 通用缓存的常见起点 |
allkeys-lfu |
从所有 key 中近似挑选使用频率较低的 | 有稳定冷热分布的缓存 |
volatile-lru / volatile-lfu |
只在有过期时间的 key 中选择 | 需要区分可淘汰 key;没有合适候选仍可能写失败 |
volatile-ttl |
优先淘汰剩余寿命较短的 key | 能接受这种优先级的缓存 |
allkeys-random / volatile-random |
在全部或可过期 key 中随机选择 | 不依赖热度排序的特定负载 |
LRU 看“最近用没用”,LFU 看“常不常用”;Redis 的实现是近似策略。内存上限与淘汰策略见官方说明。
缓存与重要会话混在一个实例中,通常很难选一个都合适的策略。不同逻辑数据库只是命名隔离,仍共享实例资源和淘汰机制,不提供独立内存上限;Cluster 也不支持这种多逻辑数据库切换。
配了 512 MiB,为什么容器仍然可能超过它¶
maxmemory 512mb 不是操作系统对进程 RSS 的硬上限。数据结构开销、分配器碎片、客户端缓冲区、复制/AOF 缓冲及后台任务都影响实际内存;部分缓冲不纳入用于淘汰判断的内存统计。
RDB/AOF 重写的子进程通过写时复制共享内存,父进程持续修改页面时,物理内存额外增长。写入越活跃,峰值可能越明显。容器限制必须留有余量,再通过压测和重写过程验证;不能将 maxmemory 与容器限制设成同一个值。
重点比较 used_memory、used_memory_rss、maxmemory,以及重写时的峰值。mem_fragmentation_ratio 在数据很少时可能很高,不能只凭一个比值就判定严重泄漏。
大 key 和热 key¶
大 key 是单个值很大、或一个集合成员很多;热 key 是访问特别频繁。它们可以同时存在,也可以完全不同。
| 问题 | 影响 | 常见处理 |
|---|---|---|
| 巨大 String | 序列化、网络传输、内存都重 | 缩小缓存结果,拆分内容,按需读取 |
| 巨大 Hash/List/Set | 全量读取、遍历或删除耗时 | 分批访问,拆结构,限制成员增长 |
| 热 key | 某个实例或分片负载集中 | 应用本地缓存、请求合并、限流,按业务拆热点 |
UNLINK 可以将适合异步的内存释放移到后台,但不会让大数据的读取与传输成本消失。分片也不会自动把一个热 key 拆开。
恢复要实际做一次¶
先在隔离环境准备相同兼容版本和配置,用已验证一致的备份恢复,检查 key 数量、关键样本、TTL、启动时长和日志。如果在恢复演练里直接使用过期很久的快照,部分 key 在加载后消失可能正是 TTL 到期,应结合时间点判断。
记录备份生成时间、文件集合、校验值、版本和恢复耗时。发现损坏时先保留原件再考虑检查/修复工具;修复可能截掉不能恢复的尾部记录。具体部署与检查见下一页。