记录 Redis 数据的持久化方式
RDB(Redis DataBase,默认持久化方式)模式
以快照的方式把数据写入文件,几十 G 可以保存为几 KB 的快照。
-
流程:
-
- fork 出一个子进程,以
copy on write
策略与父进程共享内存,将内存数据快找保存到硬盘的一个临时文件
- fork 出一个子进程,以
-
- 临时文件保存完毕,替换原有的
dump.rdb
文件
- 临时文件保存完毕,替换原有的
-
- 更新
LASTSAVE
全局变量值,该变量表示最后一次执行 SAVE 开始时的 UNIX 时间戳
- 更新
copy on write
(写时复制)技术,新 fork 出的子进程是一个独立进程,与父进程共享内存。 当父进程对某段执行写入时,会复制并更新到新的内存中,所以不会影响子进程的读取过程。 这就意味着:执行 BGSAVE时,新的操作造成的数据变更不会写入 RDB 文件- 注意文件保存位置默认是 redis 启动文件夹,可以通过
dir
配置设定 redis 工作文件夹
-
-
优点:
- 保存数据快、还原数据快
- 适用于灾难备份
- 文件以二进制保存,容量很小
-
缺点:
- 此过程可能占用大量内存,小内存机器不适合、过于频繁将导致内存占用严重
- 如果在快照间隔内发生了宕机,(内存中的)缓存数据将丢失
- 大量数据写入硬盘时,即使是后台写入,仍然会造成磁盘 IO 阻塞
-
快照条件:
- 服务器正常关闭时
shutdown
命令,同SAVE
效果。 - 满足一定间隔时间和一定据量变化后
- 执行客户端
SAVE
或BGSAVE
命令时- 如果是
SAVE
命令,直接用主进程保存,会整体卡住 - 如果是
BGSAVE
则会启动子进程,但是大量数据写硬盘,会造成磁盘阻塞 - 一般都使用
BGSAVE
- 如果是
- 如果有正在执行的 RDB 子进程,则命令会直接返回 OK
flushall
(全部删除内存数据)命令执行后会触发 rdb,避免重启后数据又回来
- 服务器正常关闭时
-
恢复条件:
- 启动时,如果有已持久化后的文件则自动加载到内存
AOF(Append-only file)模式
每次写命令,都会把命令追加写入appendonly.aof
文件。在 Redis 重启时或手动执行命令,通过命令重建整个数据库内容。
- 流程:
-
- 主进程把每条命令写入 AOF 缓冲区
-
- 有定时任务线程,把缓冲区内容写入磁盘文件
- 实际上
.aof
文件中不是直接的命令,而是经过协议优化的- 往往库也可以利用这种协议发送命令
- 缓冲区默认 1MB
-
- 优点:
- 不会造成 IO 阻塞
- 增量写入,一般不用担心丢失,写入速度快
- 缺点:
- 存储所有命令,文件容量较大
- 由于文件大,加载速度慢
- 在特定情况下(2 秒内)也可能丢少量数据
- 具体丢多少数据可以参考”dirty page”配置项,设定了最大缓冲比例
- 触发条件:
触发需要在 config 打开开关,关键是何时写到磁盘
everysec
(默认、推荐)每秒触发一次刷盘,综合性能较好always
每条数据变化都刷盘,效率低、但安全no
不主动刷盘,等待操作系统将缓存写入磁盘,批量操作效率高,但容易丢数据
- 恢复条件:
AOF 重写机制:
为了防止 aof 文件一直增大撑爆磁盘,可以根据当前内存数据生成新的 aof 文件。 比如,执行 incr 命令 1000 次,可以用一条 set x 1000 替代。
-
过程:
-
- 类似
BGSAVE
fork 子进程,共享内存,根据内存生成新的临时 aof 文件
- 类似
-
- 生成结束时,替换原有 aof 文件
-
-
触发机制:
- 重写过程会大量占用内存,所以不能过于频繁。
auto-aof-rewrite-min-size
aof 文件增长到多大后开启重写功能。 默认 64MB 太小了,我们可以改成比如 50 GB,根据内存、磁盘容量设置为合理值auto-aof-rewrite-percentage
每次触发 aof 重写的文件容量比例。 比如默认值100
,表示当前容量超过上次 100%。即上一次重写后是 10MB,当前已经到 20MB 了,就开始重写。- 手动执行
bgrewriteaof
命令
-
redis4.0 后提供了”混合持久化机制” 对 aof 重写进行了优化,aof 文件在重写时保存的格式会变为 rdb 二进制格式,容量更小。 之后再进程 aof 时,会继续以 aof 协议写入,两种格式就会混在一起,直到下次重写变为 rdb 格式。 这样大大增加了 aof 的实用性,rdb 可以不用了。
混合模式
一般以混合模式开启持久化,利用两者各自优点。
- AOF 优先级更高,一般会用 AOF
- 同时开启后,RDB 的触发频率设置应该修改为低频,避免浪费资源
其他
- 有时机器宕机时最后写磁盘动作会导致磁盘文件损坏,redis 提供了 rdb 和 aof 的文件修复工具
磁盘写入 IO 模式知识
- 磁盘 IO/NIO
- 一般使用 IO 调用 flush 后,其实并没有写盘,只是将数据放入内核 buffer 中,有可能丢数据,综合速度快
- NIO 调用
fsync
系统调用才会进行刷盘,但是这样操作虽然本次速度快,但综合下来写盘次数多,性能反而差