redis作为缓存,数据持久化是怎么做的?
在redis中提供两种持久化方案:RDB(Redis database backup view)、AOF(append only file)
这两种方式的区别
RDB文件是内存数据快照,将内存数据化持久化到硬盘上的二进制文件,在redis宕机或重启恢复的时候,方便从RDB的快照文件中恢复数据。 AOF文件是将redis操作的写、删除命令,以追加的形式存储到这个文件中。在redis宕机或重启恢复时,以从这个文件读取命令形式恢复数据
这两种方式恢复数据,那种更快?
RDB是二进制文件,保存的数据体积更小,它恢复数据更快。但是它可能丢失数据(save 秒 写指令数[新增、删除、修改])。通常项目中我们会使用AOF来恢复数据,虽然恢复的速度慢一些,但它丢失数据的风险更小些(刷盘策略选择就是每秒批量写入AOF)。
RDB基础知识
- 手动触发RDB持久化命令:
- SAVE:使用主线程创建RDB,会阻塞客户端请求
- BGSAVE:fork子进程来负责创建RDB,父进程不受影响的继续处理客户端请求
- Redis系统自动触发RDB持久化:一定时间或数据变更达到一定次数自动执行BGSAVE,可以通过Redis.conf配置文件调整自动触发的策略
- save参数:save seconds changes
- rdb压缩策略 yes/no
BGSAVE 执行原理
- fork 子进程: 当redis收到BGSAVE命令时,会调用操作系统提供的fork函数创建一个子进程;fork会复制父进程的内存空间,但这是一个copy on write的过程(父子进程共享内成页,若此时有客户端请求写入,将会创建一个新的内存页副本)
- 子进程生成RDB文件:子进程创建完成,它会读取内存页中的数据,并将其序列化为RDB格式,然后写入到磁盘上(临时文件)
- 替换旧的RDB文件:一旦子进程完成了RDB文件的生成,它将临时文件重命名为配置中RDB文件名
- 通知父进程:完成RDB文件后,会向父进程发送一个信号,告知RDB已完成。父进程将记录这次SGSAVE的结果,并可能向客户端发送通知。
AOF基础知识
AOF的手动触发命令:BGREWRITEAOF
开启AOF后,配置文件中有AOF刷盘策略、重写触发条件
-
auto-aof-rewrite-min-size:最小重写大小
-
auto-aof-rewrite-percentage :与上次重写大小相比的百分比
-
AOF刷盘策略:appendfsync 值(always每次操作都同步写到磁盘、everysec每秒同步一次、no从不主动同步)
BGREWRITEAOF 执行原理
- fork子进程:当redis收到 BGREWRITEAOF 命令时,会调用操作系统提供的fork函数创建一个子进程;fork会复制父进程的内存空间,但这是一个copy on write的过程(父子进程共享内成页,若此时有客户端请求写入,将会创建一个新的内存页副本)
- 子进程生成新的AOF文件:子进程创建完成,它会读取内存页中的数据,并生成AOF文件(遍历内存中所有数据将它们转为相应的命令)。
- 同步写入:子进程在生成新的AOF文件时,为了保证数据的一致性,若在这个过程中有新的写操作会写到老的AOF文件中以及缓存起来,以便当AOF完成后追加。
- 替换旧的AOF文件:一旦子进程完成了AOF文件的生成,它将临时文件重命名为配置中AOF文件名
- 通知父进程:完成AOF文件后,会向父进程发送一个信号,告知AOF已完成。父进程将记录这次BGREWRITEAOF的结果,并可能向客户端发送通知。