本篇重点
“对哪些数据做快照?”——关系到快照的执行效率问题
“做快照时,数据还能被增删改吗?”——关系到Redis主线程是否被阻塞,同时是否正常处理请求
前言
RDB: Redis DataBase,记录Redis运行中某一时刻的内存数据
1. 对哪些数据做快照?——全量快照 vs 增量快照
- 全量快照——把内存中的所有数据都记录到磁盘中
- 增量快照——只对一段时间内修改的数据记录快照
2. 全量快照
- 生成RDB文件的方式
- save:主线程执行RDB,会导致主线程阻塞
- bgsave:默认配置,创建子进程专门写RDB文件
- 全量快照在数据量较大时的表现
- 内存数据量\(\uparrow\),fork时间开销\(\uparrow\),阻塞主线程风险\(\uparrow\)
- 频繁写全量,磁盘压力\(\uparrow\),多个RDB竞争带宽,容易导致“前一个RDB没完,后一个RDB又开始的恶性循环”
使用增量快照代替频繁的全量快照可以有效控制数据量较大时带来的各种性能问题。
但增量快照本身有一个致命的空间消耗:需要 “记住”某一时间段内修改过的所有数据
3. 快照时数据能否修改?即写操作是否可正常执行
- 可以,借助OS的 “写时复制”技术(Copy-On-Write,COW)
- 操作:
- bgsave子进程RDB时,主线程正常执行读操作
- 对于写操作,则bgsave依旧将原先数据写盘,主线程生成该数据的副本,在副本上修改数据
- bgsave子进程RDB时,主线程正常执行读操作
- 写时复制保证快照期间数据可修改
4. 推荐持久化方案:AOF+RDB
RDB以一定的频率执行全量快照,两次RDB之间,使用AOF日志记录这段时间内的命令操作
- 既能有效防止两次RDB之间,系统宕机导致的数据丢失
- 又能避免频繁RDB导致的fork开销增加阻塞主线程
- 同时,AOF日志仅记录两次RDB间隔之间的操作,下次记录时会清空本次原有AOF日志,避免AOF重写的额外开销
5. 不同场景下AOF和RDB的选择
- 数据不能丢失:RDB+AOF
- 允许min级别的数据丢失:RDB
- 若只用AOF,则优先使用Everysec写盘策略
图片来源于极客时间专栏《Redis核心技术与实战》