redis持久化机制
作者:互联网
Redis持久化
持久化的功能就是为了避免进程退出,而导致内存中的数据永久丢失,需要定期将redis中的数据以某种形式从内存保存到硬盘;那么就可以在下次重启时通过这些持久化文件还原数据。另外,一般为了灾难备份,都会将文件拷贝到其他远程位置。
RDB持久化
触发条件
-
手动触发
有两个命令save和bsave都可以进行手动持久化。
他们之间的区别在于:
save命令会阻塞redis服务器进程,知道RDB文件创建完毕为止,缺点在于此阶段将不能处理任何命令请求;
bsave顾名思义就是backgroud save的意思,即后台备份,bsave会从主线程fork一个子线程(fork进程的时候依然会阻塞服务器,但时间相比直接save短了很多),由子线程来进行创建RDB文件,主线程则继续处理请求。 -
自动触发
自动触发需要在配置文件中配置save m n,其含义为当在m秒内发生了n此变化时,将会触发bsave;如save 100 10:当在100秒内发生了10此变化时,将会触发bsave。
-
其他触发
在主从复制的场景下,当从节点执行全量复制操作,那么主节点将会执行bsave,并将RDB文件发送给从节点。
另外执行shutdown命令时,也会执行RDB持久化。
bsave的执行流程
- redis父进程首先判断当前是否正在执行save,bsave或者bgrewriteaof,如果是,那么则直接返回。
- 父进程fork创建子进程,此过程父进程是阻塞的,不响应其他命令
- fork完成后子进程创建RDB文件,根据父进程内存快照生成临时快照文件,完成后对原有的RDB文件进行原子替换。
- 子进程发送完成信号给父进程,父进程更新save信息。
RDB文件的加载
RDB文件的载入工作是在服务器启动时自动执行的,并没有专门的命令。但是由于AOF的优先级更高,因此当AOF开启时,Redis会 优先载入AOF文件 来恢复数据;只有当AOF关闭时,才会在Redis服务器启动时检测RDB文件,并自动载入。服务器载入RDB文件期间处于阻塞状态,直到载入完成为止。
Redis载入RDB文件时,会对RDB文件进行校验,如果文件损坏,则日志中会打印错误,Redis启动失败。
AOF持久化
AOF相比于RDB不同的是,RDB是存数据快照,而AOF则是存写命令;当redis重启后可以执行AOF文件中的写命令来回复数据,与RDB相比,AOF的实时性更好,已成为主流的持久化方案。
redis默认开启RDB,关闭AOF;如果需要开启AOF,请在配置文件中加上:
appendonly yes
执行流程
因为AOF模式需要记录redis的每条写命令,所以开启后不存在手动触发模式;
1. 命令追加(append)
redis首先将写命令追加到缓冲区aof_buf,不直接写入文件
2. 文件写入(write)和文件同步(sync)
为了提高文件写入效率,在现代操作系统中,当用户调用write函数将数据写入文件时,操作系统通常会将数据暂存到一个内存缓冲区里,当缓冲区被填满或超过了指定时限后,才真正将缓冲区的数据写入到硬盘里。这样的操作虽然提高了效率,但也带来了安全问题:如果计算机停机,内存缓冲区中的数据会丢失;因此系统同时提供了fsync、fdatasync等同步函数,可以强制操作系统立刻将缓冲区中的数据写入到硬盘里,从而确保数据的安全性。
AOF缓存区的同步文件策略由参数appendfsync控制,各个值的含义如下:
- always
命令写入aof_buf后立即调用系统fsync操作同步到AOF文件,fsync完成后线程返回。这种情况下,每次有写命令都要同步到AOF文件,硬盘IO成为性能瓶颈,严重降低了Redis的性能;缓冲区似有若无。 - no
命令写入aof_buf后调用系统write操作,不对AOF文件做fsync同步;同步由操作系统负责,通常同步周期为30秒。这种情况下,文件同步的时间不可控,且缓冲区中堆积的数据会很多,数据安全性无法保证。 - everysec
命令写入aof_buf后调用系统write操作,write完成后线程返回;fsync同步文件操作由专门的线程每秒调用一次。everysec是前述两种策略的折中,是性能和数据安全性的平衡,因此是Redis的默认配置,也是我们推荐的配置。
3. 文件重写(rewrite)
随着时间流逝,Redis服务器执行的写命令越来越多,AOF文件也会越来越大;过大的AOF文件不仅会影响服务器的正常运行,也会导致数据恢复需要的时间过长。
文件重写是指定期重写AOF文件,减小AOF文件的体积。需要注意的是,AOF重写是把 Redis进程内的数据转化为写命令,同步到新的AOF文件;不会对旧的AOF文件进行任何读取、写入操作。
文件重写之所以能够压缩AOF文件,原因在于:
- 过期的数据不再写入文件
- 无效的命令不再写入文件:如有些数据被重复设值(set mykey v1, set mykey v2)、有些数据被删除了(sadd myset v1, del myset)等等
- 多条命令可以合并为一个:如sadd myset v1, sadd myset v2, sadd myset v3可以合并为sadd myset v1 v2 v3。不过为了防止单条命令过大造成客户端缓冲区溢出,对于list、set、hash、zset类型的key,并不一定只使用一条命令;而是以某个常量为界将命令拆分为多条。
文件重写的触发:
- 手动触发:直接调用bgrewriteaof命令
- 自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数,以及aof_current_size和aof_base_size状态确定触发时机
启动时加载
当AOF开启时,Redis启动时会优先载入AOF文件来恢复数据;只有当AOF关闭时,才会载入RDB文件恢复数据。
当AOF开启,但AOF文件不存在时,即使RDB文件存在也不会加载。
标签:文件,持久,AOF,Redis,redis,命令,RDB,写入,化机制 来源: https://www.cnblogs.com/leonandyou/p/15945280.html