文章目录
Redis AOF的重写机制参考博文
1.redis持久化机制是什么?
redis有两种持久化机制:RDB(默认)、AOF
2.RDB原理是什么?
原理是redis会单独创建(fork)一个与当前进程一模一样的子进程来进行持久化,这个子进程的数据和原进程一模一样,会先将数据写到一个临时文件中,持久化结束后,再用这个临时文件替换上次持久化好的文件,整个过程中,主进程不进行任何io操作,确保极高的性能。
3.RDB文件在哪?
redis.conf配置文件的dbfilename指定了rdb文件的名字(默认dump.rdb),dir指定dbfilename文件存放目录。
#rdb文件的名字。
dbfilename dump.rdb
# dbfilename文件存放目录。必须是一个目录,aof文件也会保存到该目录下。
dir ./
4.什么时候触发rdb持久化机制?
手动触发:
(1)save命令(同步):阻塞当前redis服务器,直到RDB完成,内存较大的redis实例会阻塞很久,已弃用。
(2)bgsave命令(异步)(默认):redis会fork子进程进行RDB持久化操作,完成后自动结束,阻塞发生在fork一瞬间。
自动触发:
(1)在redis.conf中的save配置,save m n ,m秒内发生n次修改就会触发RDB持久化(bgsave)。
# save ""
# 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合
# 这里表示900秒(15分钟)内有1个更改,300秒(5分钟)内有10个更改以及60秒内有10000个更改
# 如果想禁用RDB持久化的策略,只要不设置任何save指令,或者给save传入一个空字符串参数也可以
save 900 1
save 300 10
save 60 10000
(2)执行debug reload重启加载redis时,自动触发
(3)默认情况下执行shutdown时如果没有开启AOF会自动执行。
5.如何手动会发redis数据?
将备份文件(dump.rdb)移动到redis安装目录并启动服务,redis会自动加载文件到内存,redis在加载RDB文件期间会一直阻塞。
6.如何获取redis安装目录?
使用config get dir命令
7.如何停止RDB持久化?
在配置文件中修改save 注释到save m n ,加上save “”,并删掉rdb文件,重启redis
8.RDB持久化机制的优缺点?
优点:
(1)主进程不进行磁盘IO操作,fork的子进程进行磁盘IO操作,确保性能。
(2)RDB在恢复大数据集时的速度会比AOF的恢复速度快。
(3)RDB会生成多个数据文件,每个文件代表某一时间的redis数据。适合做冷备份(离线备份)。
缺点:
(1)在一段间隔时间做一次备份,如果redis挂掉,就会丢失一些数据。
(2)RDB以二进制文件保存,不同版本可能格式不一样,可能存在老版本无法兼容新版本
(3)fork子进程属于重量级操作,bgsave如果执行频率过高的话会影响性能。
补充
fork()
函数用于从一个已经存在的进程内创建一个新的进程,新的进程称为“子进程”,相应地称创建子进程的进程为“父进程”。使用fork()函数得到的子进程是父进程的复制品,子进程完全复制了父进程的资源,包括进程上下文、代码区、数据区、堆区、栈区、内存信息、打开文件的文件描述符、信号处理函数、进程优先级、进程组号、当前工作目录、根目录、资源限制和控制终端等信息,而子进程与父进程的区别有进程号、资源使用情况和计时器等。
9.RDB执行流程是什么?
执行bgsave命令后,redis主进程会检查是否存在子进程正在进行RDB/AOF操作,如果有直接返回;
主进程fork一个子进程来进行RDB操作,fork操作会对主进程造成阻塞,fork完成后会发消息给主进程,从而不再阻塞主进程。
子进程会根据redis主进程的内存生成临时文件,RDB完成后会使用临时文件替换原来的RDB文件
RDB子进程完成后会发消息个主进程,通知RDB持久化完成。
上面讲的是RDB持久化执行的主要流程,下面再讲一些细节上的东西:
在有子进程执行RDB过程的时候,Redis主进程的读写不受影响,但是对于Redis的写操作不会同步到主进程的主内存中,而是会写到一个临时的内存区域作为一个副本,等到主进程接收到子进程完成RDB过程的消息后再将内存副本中的数据同步到主内存。
Redis默认采用LZF算法对RDB文件进行压缩,所以生成的内存文件会比内存小很多。
10.AOF原理是什么?
原理是将redis的操作记录(写操作)以追加的方式写入文件。文件默认名称是appendonly.aof,redis重启时重新执行aof文件中的写操作。
11.如何开启AOF持久化?
AOf默认是关闭的,需要在redis.conf配置文件中开启
# 是否启用aof持久化方式 。否在每次更新操作后进行日志记录,Redis在默认情况下是异步的把数据写入磁盘,如果不开启,可能会在断电时导致一段时间内的数据丢失。
# 因为 redis本身同步数据文件是按上面save条件来同步的,所以有的数据会在一段时间内只存在于内存中。默认为no
appendonly yes
12.AOF的重写机制是怎样的?
AOF的原理是直接把用户插入到redis的命令追加到结尾,那么文件会越来越大,一些重复的命令也越来越多,这时可以利用BGREWRITEAOF命令来重写AOF,重写的配置:
#当AOF文件增长到一定大小的时候Redis能够调用 BGREWRITEAOF 对日志文件进行重写 。当AOF文件大小的增长率大于该配置项时自动开启重写。
auto-aof-rewrite-percentage 100
#当AOF文件增长到一定大小的时候Redis能够调用 BGREWRITEAOF 对日志文件进行重写 。当AOF文件大小大于该配置项时自动开启重写
auto-aof-rewrite-min-size 64mb
13.AOF的同步策略是怎样的?
AOF在同步内存数据到磁盘上时,并不是马上把文件写到磁盘,而是先把文件缓存到系统,然后每个30秒将文件写入磁盘,可以在配置文件中配置同步策略
#指定更新日志条件,共有3个可选值:
# no:表示等操作系统进行数据缓存同步到磁盘(快,持久化没保证)不主动同步,由操作系统决定
# always:同步持久化,每次发生数据变更时,立即记录到磁盘(慢,安全)
# everysec:表示每秒同步一次(默认值,很快,但可能会丢失一秒以内的数据)
# appendfsync always
appendfsync everysec
# appendfsync no
14.AOF的执行流程是什么?
所有的写命令都会追加到aof_buf(缓冲区)中。
可以使用不同的策略将AOF缓冲区中的命令写到AOF文件中。
随着AOF文件的越来越大,会对AOF文件进行重写。
当服务器重启的时候,会加载AOF文件并执行AOF文件中的命令用于恢复数据。
15.AOF重写流程是什么?
执行bgrewriteaof命令的时候,如果当时有进程正在执行AOF重写,那么直接返回,如果有进程正在执行bgsave,那么等待bgsave执行完毕后在执行AOF重写
Redis主进程会fork一个子进程进行AOF重写。
AOF重写过程中,不影响redis原有的AOF过程,包括写消息到AOF缓存以及同步AOF缓存中的数据到磁盘
AOF重写过程中,主进程收到的写操作还会将命令写到AOF重写缓冲区
由于AOF重写过程中原AOF文件还在陆续写入数据,所以AOF重写子进程只会拿到fork子进程时的AOF文件进行重写
子进程拿到原AOF文件中的数据写到一个临时的AOF文件中
子进程完成AOF重写后会发消息给主进程,主进程会把AOF重写缓存区的数据写到AOF缓冲区,并且用新的AOF文件替换就得AOF文件
16.如果redis在append数据到AOF文件时,机器宕机了怎么修复?
如果redis在append数据到AOF文件时,机器宕机了,可能会导致AOF文件破损 ,可以使用redis-check-aof --fix命令来修复破损的AOF文件
17.AOF重写的整个过程有哪几部分会阻塞进程?
主进程fork子进程时
主进程把AOF重写缓冲区的数据写到AOF缓冲区时
使用新的AOF文件替换就得AOF文件时
18.如果aof和rdb同时存在,听谁的?
AOF
19.总结
RDB基于内存快照存储二进制文件;AOF基于写命令存储文本文件
RDB文件采用了压缩算法,比较小;AOF随着命令的增多会越来越大,通过AOF重写来压缩AOF文件
恢复RDB文件速度比AOF文件快很多
RDB实时性不好