持久化
为什么要持久化?
很多时候我们需要持久化数据也就是将内存中的数据写入到硬盘里面,大部分原因是为了之后重用数据(比如重启机器、机器故障之后恢复数据),或者是为了防止系统故障而将数据备份到一个远程位置。将备份文件 (dump.rdb) 移动到 redis 安装目录并启动服务即可,redis就会自动加载文件数据至内存了。Redis 服务器在载入 RDB 文件期间,会一直处于阻塞状态,直到载入工作完成为止。
redis提供两种方式进行持久化,一种是RDB持久化(原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化),另外一种是AOF(append only file)持久化(原理是将Reids的操作日志以追加的方式写入文件)。
RDB
什么是RDB
RDB是Redis用来进行持久化的一种方式,是把当前内存中的数据集快照写入磁盘,也就是 Snapshot 快照(数据库中所有键值对数据)。恢复时是将快照文件dump.rdb直接读到内存里。
RDB原理
当redis需要做持久化时(执行SAVA或者BGSAVA命令,或者是达到配置条件时执行),redis会fork一个子进程,子进程将数据写到磁盘上一个临时RDB文件中,当子进程完成写临时文件后,将原来的RDB替换掉(默认文件名为dump.rdb)
触发条件
自动触发:
-
save m n
save m n
是指在 m 秒内,如果有 n 个键发生改变,则自动触发持久化。 -
flushall
flushall
命令用于清空 Redis 数据库,在生产环境下一定慎用,当 Redis 执行了flushall
命令之后,则会触发自动持久化,把 RDB 文件清空。 -
主从同步触发
在 Redis 主从复制中,当从节点执行全量复制操作时,主节点会执行
bgsave
命令,并将 RDB 文件发送给从节点,该过程会自动触发 Redis 持久化。
手动触发:
-
save 命令
在客户端中执行
save
命令,就会触发 Redis 的持久化,但同时也是使 Redis 处于阻塞状态,直到 RDB 持久化完成,才会响应其他客户端发来的命令,所以在生产环境一定要慎用。 -
bgsave 命令
bgsave(background save)既后台保存的意思, 它和
save
命令最大的区别就是bgsave
会 fork() 一个子进程来执行持久化,整个过程中只有在 fork() 子进程时有短暂的阻塞,当子进程被创建之后,Redis 的主进程就可以响应其他客户端的请求了
优缺点
优点:
- RDB 的内容为二进制的数据,占用内存更小,更紧凑,更适合做为备份文件;
- RDB 对灾难恢复非常有用,它是一个紧凑的文件,可以更快的传输到远程服务器进行 Redis 服务恢复;
- RDB 可以更大程度的提高 Redis 的运行速度,因为每次持久化时 Redis 主进程都会 fork() 一个子进程,进行数据持久化到磁盘,Redis 主进程并不会执行磁盘 I/O 等操作;
- 与 AOF 格式的文件相比,RDB 文件可以更快的重启
缺点:
- RDB 需要经常 fork() 才能使用子进程将其持久化在磁盘上。如果数据集很大,fork() 可能很耗时,并且如果数据集很大且 CPU 性能不佳,则可能导致 Redis 停止为客户端服务几毫秒甚至一秒钟。
- 在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改(数据有丢失)。
AOF
什么是AOF
RDB持久化是将进程数据写入文件,而AOF持久化(即Append Only File持久化),则是将Redis执行的每次写命令记录到单独的日志文件中(有点像MySQL的binlog);当Redis重启时再次执行appendonly.aof文件中的命令来恢复数据,aof默认是不开启的
原理
以日志的形式来记录每个写操作,将Redis执行过的所有指令记录下来(读操作不记录) , 只许追加文件但不可以改写文件, redis启动之初会读取该文件重新构建数据,换言之, redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作
appendonly.aof
使用redis-check-aof修复aof文件
aof自动重写
AOF 持久化是通过保存被执行的写命令来记录数据库状态的,所以AOF文件的大小随着时间的流逝一定会越来越大;为了解决AOF文件体积膨胀的问题,Redis提供了AOF重写功能:Redis服务器可以创建一个新的AOF文件来替代现有的AOF文件,新旧两个文件所保存的数据库状态是相同的,但是新的AOF文件不会包含任何浪费空间的冗余命令,通常体积会较旧AOF文件小很多。
#假设服务器对键list执行了以下三条命令:
127.0.0.1:6379[1]> RPUSH list 1 2 3 4 //[1,2,3,4]
127.0.0.1:6379[1]> RPOP list //[1,2,3]
127.0.0.1:6379[1]> LPOP list //[2,3]
#当前列表键list在数据库中的值就为[2,3]。要保存这个列表的当前状态,并且尽量减少使用的命令数,最简单的方式不是去AOF文件分析前面执行的三条命令,而是直接读取list键在数据库中的当前值,然后用一条RPUSH 2,3代替前面的三条命令。
优缺点
优点:
- 使用
AOF
机制,可以自由选择不同fsync
(刷盘)策略,而且在默认策略下最多也仅仅是损失1s
的数据,实时性和完整性强。 AOF
日志是一个仅追加的日志,因此如果出现断电,也不存在查找或损坏问题。即使由于某些原因(磁盘已满或其它原因),日志已经写了一半的命令结束,redis-check-aof
工具也能够轻松地修复它。- 当
AOF
文件变得太大时,Redis
能够在后台自动重写。 - 不同于
RDB
的文件格式,AOF
是一种易于理解和解析的格式,依次包含所有操作的日志。
缺点:
- 对于相同的数据集,
AOF
文件通常比等效的RDB
文件大,恢复速度较慢 - 根据
fsync
的具体策略,AOF
机制可能比RDB
机制慢。但是一般情况下,fsync
设置为每秒的性能仍然很高,禁用fsync
后,即使在高负载下,它的速度也能和RDB
一样快。 - 因为 AOF 文件的个别命令,可能会导致在加载时失败,从而无法进行数据恢复。可能存在
BRPOP
、LPUSH
等阻塞命令的错误,从而导致生成的AOF
在重新加载时不能复制完全相同的数据集.