Redis 数据持久化方案的介绍及应用

833 阅读5分钟

RDB

原理是fork和cow,fork是指redis通过创建子进程来进行RDB操作,cow指的是copy on write,子进程创建后,父子进程共享数据段,父进程继续提供读写服务,写脏的页面数据会逐渐和子进程分离开来

RDB是对Redis中的数据执行周期性的持久化

适合做冷备份

优点

会生成多个数据文件,每个数据文件分别都代表了某一时刻Redis里面的数据,完整的数据运维设置定时任务,定时同步到远端的服务器,一旦线上挂了,你想恢复多少分钟之前的数据,就去远端拷贝一份之前的数据就行

RDB对Redis的性能影响非常小,因为在同步数据时,他只是fork了一个子进程去做持久化,在数据恢复的时候速度比AOF快

缺点

RDB是快照文件,都是默认五分钟甚至更久的时间才会生成一次,意味着这中间五分钟的数据很可能全部丢失,而AOF则最多丢一秒的数据

RDB在生成数据快照的时候,如果文件很大,客户端可能会暂停几毫米甚至几秒,如果在高负载的时候正好fork了一个子进程去生成一个大快照,就出大问题了

AOF

对每条写入命令作为日志,以append-only的模式写入一个日志文件中,因为这个模式是只追加的方式,所以没有任何磁盘寻址的开销,所以很快,类似于mysql中的binlog

适合做热备

优点

AOF是一秒一次去通过一个后台的线程fsync操作,最多丢这一秒的数据

AOF在对日志文件进行操作的时候是以append-only的方式去写,只是追加的方式写数据,自然写入性能很好,文件也不容易损坏

AOF的日志是通过一个叫非常可读的方式记录,这样的特性就适合做灾难性数据误删除的紧急恢复

缺点

一样的数据,AOF文件比RDB要大

AOF开启后,Redis支持写的QPS会比RDB支持写的低,当然即使这样性能还是很高

实际应用

RDB做镜像全量持久化,AOF做增量持久化

因为RDB会耗费较长时间,不够实时,在停机的时候会导致大量丢失数据,所以需要AOF来配合使用

在Redis实例重启时,会使用RDB持久化文件重新构建内存,再使用AOF重放近期的操作指令来实现完整恢复重启之前的状态

数据丢失问题

例如服务器掉电是否会丢失数据

取决于AOF日志sync属性的配置,如果不要求性能,在每条写指令时都sync一下磁盘,就不会丢失数据

但是实际生产中,通常对高性能有要求,一般都是用定时sync,例如1秒1次,这个时候最多会丢失1s的数据

RDB和AOF对比

同步机制

Redis可以使用主从同步,从从同步。

第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将RDB文件全量同步到复制节点,复制节点接受完成后将RDB镜像加载到内存。

加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。

后续的增量数据通过AOF日志同步即可,有点类似数据库的binlog

命令说明

SAVE

时间复杂度: O(N), N 为要保存到数据库中的 key 的数量。

功能说明

SAVE 命令执行一个同步保存操作,将当前 Redis 实例的所有数据快照(snapshot)以 RDB 文件的形式保存到硬盘。

一般来说,在生产环境很少执行 SAVE 操作,因为它会阻塞所有客户端,保存数据库的任务通常由 BGSAVE 命令异步地执行。然而,如果负责保存数据的后台子进程不幸出现问题时, SAVE 可以作为保存数据的最后手段来使用

返回值

保存成功时返回ok

示例

redis> SAVE
OK

BGSAVE

时间复杂度: O(N), N为要保存到数据库中的key的数量

功能说明

在后台异步(Asynchronously)保存当前数据库的数据到磁盘

BGSAVE 命令执行之后立即返回 OK ,然后 Redis fork 出一个新子进程,原来的 Redis 进程(父进程)继续处理客户端请求,而子进程则负责将数据保存到磁盘,然后退出。

BGREWRITEAOF

时间复杂度: O(N)

功能说明

执行一个AOF文件重写操作。重写会创建一个当前 AOF 文件的体积优化版本。

即使 BGREWRITEAOF 执行失败,也不会有任何数据丢失,因为旧的 AOF 文件在 BGREWRITEAOF 成功之前不会被修改。

重写操作只会在没有其他持久化工作在后台执行时被触发,也就是说:

如果 Redis 的子进程正在执行快照的保存工作,那么 AOF 重写的操作会被预定(scheduled),等到保存工作完成之后再执行 AOF 重写。在这种情况下, BGREWRITEAOF 的返回值仍然是 OK ,但还会加上一条额外的信息,说明 BGREWRITEAOF 要等到保存操作完成之后才能执行。在 Redis 2.6 或以上的版本,可以使用 INFO [section] 命令查看 BGREWRITEAOF 是否被预定。

如果已经有别的 AOF 文件重写在执行,那么 BGREWRITEAOF 返回一个错误,并且这个新的 BGREWRITEAOF 请求也不会被预定到下次执行。

从 Redis 2.4 开始, AOF 重写由 Redis 自行触发, BGREWRITEAOF 仅仅用于手动触发重写操作。

返回值

反馈信息

示例

redis> BGREWRITEAOF
Background append only file rewriting started

LASTSAVE

时间复杂度: O(1)

功能说明

返回最近一次 Redis 成功将数据保存到磁盘上的时间,以 UNIX 时间戳格式表示

返回值

一个 UNIX 时间戳

示例

redis> LASTSAVE
(integer) 1324043588