一、底层产品设计定位(根源区别)
- Redis :内存数据库,核心目标是高性能读写 ,所有数据优先驻留内存,RDB、AOF 持久化只是附加的故障备份功能,设计初衷从来不是长期可靠落地海量业务数据;
- MySQL-InnoDB :磁盘型关系数据库,持久落盘是核心本职,原始数据永久存储在磁盘文件,BufferPool 只是磁盘数据的内存缓存,内存只是加速,不承载数据本源。
定位从底层决定:Redis 持久是 "备胎",DB 持久是 "本职"。
二、Redis 两大持久化机制:RDB、AOF 原理 + 各自缺陷(丢数根源)
1.RDB(快照持久化,快照 = 某一瞬间全量数据二进制文件)
原理
触发方式三种:① 配置save 秒 变更次数自动触发;② 手动bgsave(fork 子进程后台生成 rdb,不阻塞主线程)、save(阻塞全库);③ redis 正常 shutdown 自动生成 RDB。执行时 fork 子进程,把当前内存所有数据序列化生成.rdb二进制文件存磁盘。
优点
文件压缩紧凑、体积小、全量恢复速度极快,适合冷备份。
致命短板(不能做主持久)
- 时间间隙大面积丢数据 :两次 RDB 快照之间新增 / 修改的数据只存在内存,没有落地磁盘,如果宕机、断电,这段时间数据全部永久丢失;配置 RDB 越频繁耗 CPU、IO,低频则丢数据越多。
- 大实例 fork 子进程会瞬时占用双倍内存,服务器内存不足容易 OOM。
2.AOF(增量日志持久化,记录每一条修改指令)
原理
所有写指令 (set/hset 等) 以文本格式追加写入.aof日志文件,重启时回放 AOF 命令还原数据;提供 3 种刷盘策略:
| 策略 | 规则 | 数据丢失 | 性能影响 |
|---|---|---|---|
| always | 每条命令写完立刻调用 fsync 刷物理磁盘 | 0 丢失 | 性能暴跌,丧失 Redis 高速优势,生产几乎不用 |
| everysec(默认) | 命令写入系统页缓存,后台线程每秒统一 fsync 刷盘 | 宕机最多丢失 1 秒数据 | 性能均衡,生产默认 |
| no | 交给操作系统自主调度刷盘 | 丢失数据不可控 | 性能最优 |
AOF 衍生问题:AOF 重写 (rewrite)
AOF 持续追加指令,日志会无限膨胀(比如反复对同一个 key set 1、set2,日志重复冗余),因此触发重写:新开子进程,读取当前内存有效数据,生成精简版新 AOF,替换旧文件。
- 重写硬性缺点 :生成新 AOF 期间,磁盘需要同时保存旧 AOF + 新 AOF 临时文件 ,占用双倍磁盘空间;磁盘剩余空间不足时重写失败,触发
MISCONF异常,整个 Redis 停止接收所有写入请求。
混合持久化 (aof-use-rdb-preamble)
AOF 头部存 RDB 快照、后续增量存 AOF 指令,只是折中优化,无法解决 everysec 一秒丢数、重写占磁盘的原生问题。
小结 RDB+AOF 同开(生产标配)
AOF 兜底日常少量丢数,RDB 做冷备份;依然做不到已提交数据 100% 落地磁盘,无法满足金融、订单等零丢失持久场景。
三、写入应答机制核心区别(最关键:客户端收到成功代表的含义不同)
1.Redis
客户端发送写入指令→数据写入 Redis 内存缓冲区,立刻返回 OK ;RDB/AOF 落盘是后台异步线程 / 子进程操作,落盘动作和客户端响应完全解耦。
拿到成功 ≠ 数据落地硬盘,宕机大概率丢数。
2.MySQL InnoDB
事务执行 DML 修改 BufferPool 内存,不会立刻返回成功 ;事务commit提交时,强制调用 fsync 把 redo 日志写入物理磁盘,redo 落地成功才向客户端返回执行成功,配合 binlog 两阶段提交。
拿到成功 = 关键日志已经落地物理磁盘,断电宕机依靠磁盘 redo 重做事务,已提交数据绝不丢失,未提交自动回滚。
四、磁盘文件容量、空间管理区别
1.Redis
- RDB:定时全量生成大体积快照文件,频繁生成占用大量磁盘;
- AOF:日志持续膨胀,重写依赖额外冗余磁盘,磁盘爆满直接锁库禁止写入;
- 内存淘汰导致文件数据失真 :配置
maxmemory上限,数据超内存触发 LRU/LFU 淘汰,内存中冷数据被直接删除,但 RDB/AOF 持久文件不会同步删除这条数据,持久文件残留无效脏数据,用备份文件恢复后数据错乱。
2.MySQL InnoDB
- 数据分散在
.ibd数据文件、redo、binlog 日志,采用页式存储,自带碎片整理、表空间压缩、分区表、自动空间回收; - 磁盘空间不足:仅当前执行的单条事务失败回滚,数据库整体正常运行,不会全库锁写入;
- BufferPool 只是磁盘数据缓存,缓存被淘汰,原始业务数据永久保存在磁盘,文件和实际数据永远一致。
五、事务、数据一致性能力差距
- Redis 事务 :
MULTI/EXEC仅批量打包命令,不支持事务回滚、无隔离级别、不满足 ACID,中间指令报错不会回滚前面执行成功的命令,无法实现跨行、跨表强一致性业务; - InnoDB:完整 ACID、MVCC 多版本隔离、行级锁、外键约束,支持复杂多表事务,账务、订单扣款等强一致性业务唯一选择。
六、数据模型与查询能力
- Redis:仅 KV+5 种基础数据结构(String/List/Hash/Set/ZSet),无 SQL、无多表关联、无复杂聚合查询、无约束,复杂报表、多条件筛选无法实现;
- MySQL:关系型模型,支持 SQL、多表 JOIN、复杂聚合、索引、主键 / 唯一 / 非空约束,适配绝大多数业务查询需求。
七、硬件存储成本
- Redis 数据依托内存,内存硬件单价远高于 SSD 磁盘,TB 级海量全量存储成本极高;
- MySQL 主体数据存磁盘,HDD/SSD 成本低廉,轻松支撑几十 TB 业务数据。
八、总结落地规范
- ✅ Redis 适用:热点缓存、临时会话、活动计数、排行榜,允许少量数据丢失,RDB+AOF 仅用来缓存故障重启快速恢复;
- ✅ MySQL 适用:订单、用户资产、财务流水等核心业务持久化,要求已写入数据永久落地、零丢失。