🏳️🌈个人网站:code宝藏 👈,欢迎访问🎉🎉
🙏如果大家觉得博主写的还不错的话,可以点点关注,及时获取我的最新文章
🤝非常感谢大家的支持与点赞👍
📚这个是我看《redis开发与运维》的笔记,有些地方看了网上的一些技术文章作为补充,具体参考链接在文末
RDB
RDB持久化是把当前进程数据生成快照保存到硬盘的过程,Redis 的快照是全量快照,也就是说每次执行快照,都是把内存中的「所有数据」都记录到磁盘中,所以执行快照是一个比较重的操作
触发机制
(1)save:阻塞当前Redis服务器,直到RDB过程完成为止 (不推荐)
(2)bgsave: Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责 (推荐)
bgsave是主流的触发RDB持久化方式
流程说明
- 执行bgsave命令,如果有存在正在执行的子进程,这直接返回
- 执行fork操作创建子进程,fork完成后父进程可以继续响应其他命令
- 子进程根据父进程内存生成临时快照文件,完成后替换原有RDB文件,通知父进程完成
AOF
AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性
-
AOF 文件的内容是操作命令;
-
RDB 文件的内容是二进制数据。
工作流程
1)所有的写人命令会追加到aof_buf(缓冲区)中。
2)AOF 缓冲区根据对应的策略向硬盘做同步操作。
3)随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的。
4)当Redis服务器重启时,可以加载AOF文件进行数据恢复。
文件同步策略
Redis提供了多种AOF 缓冲区同步文件策略,由参数appendfsync控制
-
always
命令写入aof_buf后调用系统fsync操作同步到AOF文件,fsync完成后线程返回
-
everysec
命令写人aof_buf后调用系统write操作,write完成操作后线程返回。fsync同步文件操作由专门线程每秒调用一次
-
no
命令写人aof_buf后调用系统write操作,不对AOF文件做fsync同步,同步硬盘操作由操作系统负责,通常同步周期最长30秒
系统调用write和fsync
调用wirte的时候,会将aof缓存区的文件先放入到内核缓存区中,然后再由fsync放入到硬盘中,所以调用wirte的本质还是调用fsync
由此我们可知三种同步策略只是在控制fsync()函数的调用时机不同而已。
-
Always 策略就是每次写入 AOF 文件数据后,就执行 fsync() 函数;
-
Everysec 策略就会创建一个异步任务来执行 fsync() 函数;
-
No 策略就是永不执行 fsync() 函数;
重写机制
AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程
重写的aof文件为什么变小?
-
进程内已经超时的数据不再写人文件。
-
旧的AOF文件含有无效命令,比如del key1,重写使用进程内数据直接生成,只保留最终数据的写入命令
-
多条写命令可以合并为一个
工作流程
- 执行AOF重写请求。
如果当前进程正在执行AOF重写,请求不执行 - 父进程执行fork创建子进程来执行重写操作,fork完成后可以继续响应其他命令
- 由于fork操作运用写时复制技术,子进程只能共享fork操作时的内存数据。由于父进程依然响应命令,Redis使用“AOF重写缓冲区”保存这部分新数据,防止新AOF文件生成期间丢失这部分数据。
- 重写完成后,子进程发送信号给父进程,父进程把AOF重写缓存区写入到新的AOF文件中
- 将新AOF文件替换老文件
重启加载
- AOF持久化开启且存在AOF文件时,优先加载AOF文件
- AOF关闭或者AOF文件不存在时,加载RDB文件
- 加载AOF/RDB文件成功后,Redis启动成功
- AOF/RDB文件存在错误时,Redis启动失败并打印错误信息
写时复制技术
在RDB的bgsave中跟AOF的重写中都用到了写时复制技术,它可以使得子进程在操作的过程中,当父进程需要修改数据时,不会互相影响。通过 fork()
创建子进程后,此时子进程和父进程是共享同一片内存数据的,因为创建子进程的时候,会复制父进程的页表,但是页表指向的物理内存还是一个。
这样一来,子进程就共享了父进程的物理内存数据了,这样能够节约物理内存资源,页表对应的页表项的属性会标记该物理内存的权限为只读。
不过,当父进程或者子进程在向这个内存发起写操作时,CPU 就会触发缺页中断,这个缺页中断是由于违反权限导致的,然后操作系统会在「缺页异常处理函数」里进行物理内存的复制,并重新设置其内存映射关系,将父子进程的内存读写权限设置为可读写,最后才会对内存进行写操作,这个过程被称为「写时复制 (Copy On Write)」。
参考链接