RDB持久化和AOF持久化

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Hzt_fighting_up/article/details/78633169

为什么需要持久化
因为Redis是内存数据库,服务器进程退出,服务器中的数据库状态也会消失

RDB持久化
将内存中的数据库状态保存到磁盘文件里,防止数据丢失

1)生成RDB文件命令:SAVE、BGSAVE
SAVE命令:
由服务器进程去执行持久化的过程,会造成阻塞,在生成RDB文件的过程中,服务器不能处理任何客户端请求的命令。
BGSAVE命令:创建一个子进程去生成RDB文件,服务器进程处理客户端的请求。在执行BGSAVE命令的时候,服务器进程会拒绝服务端发送的SAVE、BGSAVE请求,避免产生竞争条件。同时也会拒绝BGREWRITEAOF(后台重写),因为同时进行持久化会造成大量的磁盘写入操作,影响性能。同时,服务器可以通过修改配置文件的save选项,定期执行BGSAVE命令。默认配置的save选项:

save 900 1
save 300 10
save 60 10000

save选项可以有多个,只要其中任意一个条件被满足,服务器就会执行BBGSAVE命令。save 900 1 表示的意思为服务器在900秒之内对数据进行了至少1次修改,则BGSAVE命令就会被执行(服务器的周期性执行函数serverCron默认每隔100毫秒就执行一次,此时会检查save选项所设置保存的值是否满足条件,如果满足的话就执行BGSAVE命令。服务器会保存上一次执行save/bgsave的时间和自从上一次执行持久化操作以后对数据库进行修改的次数。根据这两个值来判断是否满足save条件。serverCron函数依次遍历saveParam数组中的所有保存条件,只要有任意一个条件被满足,服务器就会执行。save条件被保存在一个数组中)

SAVE和BGSAVE的区别是是否会创建一个子进程去生成RDB文件。

缺点:两次持久化之间,可能会导致数据的丢失

2)载入RDB文件
服务器启动时自动执行的,如果服务器启动时检测到RDB文件的存在就会自动载入RDB文件。(如果服务器开启了AOF持久化功能,将先使用AOF文件来还原数据库,只有在AOF功能关闭的时候才使用RDB文件还原数据库)
服务器在载入RDB文件期间,会处于阻塞状态,直到载入工作完成

AOF持久化
AOF持久化通过保存Redis服务器所执行的写命令来记录数据库状态的。即保存客户端的命令,但是客户端的命令是以命令请求协议格式保存的
AOF持久化分为命令追加、文件写入、文件同步
命令追加:当配置文件中开启了AOF持久化功能时,服务器在执行完一条命令以后,会以协议格式将执行的命令追加到服务器状态的aof_buf缓冲尾末尾
文件写入:将auto_buf中的内容通过调用flushAppendOnlyFile函数写入和保存到AOF文件当中。flushAppendOnlyFile函数的行为由服务器配置的appendfsync选项的值来确定,默认为everysec,,将a0f_buf缓冲区中的所有内容写到AOF文件,如果上次同步AOF文件的时间距离现在超过一分钟,则再次对AOF文件进行同步,并且这个同步操作是由同一个线程专门负责的
文件同步:为什么会出现同步问题,为了提高文件的写入效率,在现代操作系统中,当用户调用write函数时(即将一些数据写入到文件的时候),操作系统通常会将写入数据暂时保存在一个内存缓冲区里面,等到缓冲区被填满、或者超过了指定的时间以后,才正真将缓冲区的数据写到磁盘里面,但会带来问题,如果计算机突然停机,则内存缓冲区中的数据将丢失。redis中有两个函数fsync和fdatasync,强制让操作系统把缓冲区中的数据立刻写入到磁盘中。
AOF文件载入:
1)创建一个不带网络连接的伪客户端,因为所有命令只能在客户端执行,并且使用的命令来自AOFG而不是网络里阿尼金额,所以可以创建一个没有连接的伪客户端
2)从AOF文件中分析并读取出一条写命令
3)使用伪客户端版执行被读出的写命令
4)重复执行2)3)直到所有写命令都被处理完毕为止
AOF重写:为了解决AOF文件体积膨胀的问题。调用aof_rewrite函数
实质:从数据库中读取键现在的值,然后用一条命令去记录键值对代替之前记录这个键值对的多条命令。AOF重写并不需要对现有的AOF文件进行任何读取分析或写入操作。为了避免在执行命令的时候造成客户端输入缓冲区溢出,会先检查键所包含的元素数值,如果元素数量超过了REDIS_AOF_REWRITE_ITEMS_PER_CMD常量值(默认为64),则会使用多条命令来记录键的值
AOF后台重写:调用aof_rewrite函数重写会造成阻塞,因为由服务器进程调用aof_rewrite,所以在重写期间,服务器无法处理来自客户端的请求。AOF后台重写就是将AOF重写放到子进程里执行。
使用子进程执行AOF重写会出现数据库状态不一致性问题,因为此时服务器进程仍能处理客户端的命令请求
如何解决AOF后台重写出现的数据库不一致问题:redis服务器设置了一个AOF重写缓冲区,这个缓冲区在服务器创建子进程以后使用,当redis服务器执行完一条命令以后,会将命令同时发送给AOF缓冲区和AOF重写缓冲区。
AOF后台重写过程:
1)执行客户端发送的命令
2)将执行以后的写命令追加到AOF缓冲区
3)将执行以后的写命令追加到AOF重写缓冲区中
当子进程执行完成AOF重写以后会继续执行
4)将AOF重写缓存区中的所有内容都写到新的
小结:如果开启了AOF持久化,则AOF持久化和AOF后台重写应该是同时进行的,重写以后的aof文件会替换原来的aof文件(自己理解)

RDB持久化和AOF持久化的区别

猜你喜欢

转载自blog.csdn.net/Hzt_fighting_up/article/details/78633169