Redis持久化

redis学习笔记——RDB和AOF持久化一

因为AOF文件的更新频率通常比RDB文件的更新频率高,所以如果服务器开启了AOF持久化功能,那么服务器会优先使用AOF文件来还原数据库状态。只有在AOF持久化功能处于关闭状态时,服务器才会使用RDB文件来还原数据库状态。

redis持久化:

两种方式:rdb(redis database)和aof(append of file)

RDB:

在指定时间间隔内,将内存中的数据作为一个快照文件(snapshot)写入到磁盘,读取的时候也是直接读取snapshot文件到内存中

①持久化过程:redis单独创建(fork)一个进程来持久化,会先将数据写入临时文件中,待上次持久化结束后,会将该临时文件替换上次持久化文件,比aof高效,但是最后一次数据可能会丢失

②Fork:在linux中,fork()会产生一个跟主进程一样的子进程,出于效率考虑,主进程和子进程会公用一段物理内存,当发生改变的时候,才会把主进程“”写时复制”一份给子进程

③Redis备份的文件:在redis.conf中设置,dbfilename默认为:dump.rdb

Redis提供了save和bgsave两个命令来生成RDB文件(即将内存数据写入RDB文件中),执行成功后我们在磁盘中找到该RDB文件(dump.rdb)

两个Redis命令可以用于生成RDB文件,一个是SAVE,另一个是BGSAVE

两者区别:

SAVE命令会阻塞Redis服务器进程,直到RDB文件创建完毕为止,在服务器进程阻塞期间,服务器不能处理任何命令请求;

BGSAVE命令会派生出一个子进程,然后由子进程负责创建RDB文件,服务器进程(父进程)继续处理命令请求;

创建RDB文件的实际工作由rdb.c/rdbSave函数完成,SAVE命令和BGSAVE命令会以不同的方式调用这个函数

手动快照:

如果没有触发自动快照,可以对redis进行手动快照操作,SAVE和BGSAVE都可以执行手动快照,两个命令的区别是前者是由主进程进行快照操作,会阻塞其他请求;而后者是通过fork子进程进行快照操作

注意:

由于redis使用fork来复制一份当前进程,那么子进程就会占有和主进程一样的内存资源,比如说主进程8G内存,那么在备份的时候必须保证有16G内存,要不然会启用虚拟内存,性能非常差。

Redis的持久化-RDB

Redis的持久化-AOF

RDB文件中存放的是二进制数据

④ Rdb保存策略:

900s 1 file change

300s 10file change

60s 10000file change

Redis持久化
  

⑤Rdb的备份:

config get dir 得到备份的文件夹

复制备份文件

⑥Rdb恢复:

关闭redis

将备份文件复制到工作目录下

启动redis,自动加载

AOF :

 以日志形式记录每个写操作,启动时通过日志恢复操作

开启AOF:默认不开启,进入redis.conf找到appendonly yes打开

修复AOF:redis-check-aof –fix appendonly.aof

同步频率:每秒记录一次,如果宕机该秒记可能失效

Rewrite:bgrewrite  aof 因为日志是追加方式,文件会越来越大,当超过了设置的阈值时,日志文件会压缩,保留仅可以恢复的日志

AOF重写

重写是为了解决AOF文件越来越大的问题,所以需要将他的体积缩小。

AOF文件重写的实现

首先从数据库中读取键现在的值,然后用一条命令去记录键值对,代替之前记录这个键值对的多条命令,这就是AOF重写功能的实现原理

如:

redis> SADD animals "Cat"            

   // {"Cat"}

(integer) 1

redis> SADD animals "Dog" "Panda" "Tiger"    // {"Cat", "Dog", "Panda", "Tiger"}

(integer) 3

redis> SREM animals "Cat"                    // {"Dog", "Panda", "Tiger"}

(integer) 1

redis> SADD animals "Lion" "Cat"             // {"Dog", "Panda", "Tiger", 

(integer) 2                                     "Lion", "Cat"}

可以用:

SADD animals"Dog""Panda""Tiger""Lion""Cat" 命令代替。

aof的重写是也是放在子程序中进行。不过,使用子进程也有一个问题需要解决,因为子进程在进行AOF重写期间,服务器进程还需要继续处理命令请求,而新的命令可能会对现有的数据库状态进行修改,从而使得服务器当前的数据库状态和重写后的AOF文件所保存的数据库状态不一致。

为了解决这种数据不一致问题,Redis服务器设置了一个AOF重写缓冲区这个缓冲区在服务器创建子进程之后开始使用,当Redis服务器执行完一个写命令之后,它会同时将这个写命令发送给AOF缓冲区和AOF重写缓冲区,如图所示:


Redis持久化
 

这也就是说,在子进程执行AOF重写期间,服务器进程需要执行以下三个工作:

1)执行客户端发来的命令;

2)将执行后的写命令追加到AOF缓冲区;

3)将执行后的写命令追加到AOF重写缓冲区。

这样一来可以保证:

a、AOF缓冲区的内容会定期被写入和同步到AOF文件,对现有AOF文件的处理工作会如常进行。

b、从创建子进程开始,服务器执行的所有写命令都会被记录到AOF重写缓冲区里面。

当子进程完成AOF重写工作之后,它会向父进程发送一个信号,父进程在接到该信号之后,会调用一个信号处理函数,并执行以下工作:

1)将AOF重写缓冲区中的所有内容写入到新AOF文件中,这时新AOF文件所保存的数据库状态将和服务器当前的数据库状态一致。

2)对新的AOF文件进行改名,原子地(atomic)覆盖现有的AOF文件,完成新旧两个AOF文件的替换。

这个信号处理函数执行完毕之后,父进程就可以继续像往常一样接受命令请求了。

注意:

在整个AOF后台重写过程中,只有信号处理函数执行时会对服务器进程(父进程)造成阻塞,在其他时候,AOF后台重写都不会阻塞父进程,这将AOF重写对服务器性能造成的影响降到了最低。

=================================================================

RDB优点:

节省磁盘空间

恢复速度快

缺点:

数据太大时,比较消耗性能

一段时间保存一次快照,宕机时最后一次可能没有保存

AOF优点:

备份机制更加稳健

可读的日志文件,通过aof恢复更加稳健,可以处理失误

缺点:

比RDB更占磁盘

备份速度较慢

每次都同步日志,有性能压力

RDB和AOF哪个好

官方推荐都启用

对数据不敏感,单独用RDB

不建议单独使用AOF

若作为纯缓存使用,可以都不开启

相关推荐