侧边栏壁纸
博主头像
一定会去到彩虹海的麦当

说什么呢?约定好的事就一定要做到啊!

  • 累计撰写 63 篇文章
  • 累计创建 16 个标签
  • 累计收到 3 条评论

目 录CONTENT

文章目录

[redis]——持久化

一定会去到彩虹海的麦当
2022-04-19 / 0 评论 / 0 点赞 / 42 阅读 / 1,888 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2022-05-17,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

这个是我看《redis开发与运维》的笔记,有些地方看了网上的一些技术文章作为补充,具体参考链接在文末

RDB

RDB持久化是把当前进程数据生成快照保存到硬盘的过程,Redis 的快照是全量快照,也就是说每次执行快照,都是把内存中的「所有数据」都记录到磁盘中,所以执行快照是一个比较重的操作

触发机制

(1)save:阻塞当前Redis服务器,直到RDB过程完成为止 (不推荐)

(2)bgsave: Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责 (推荐)

bgsave是主流的触发RDB持久化方式

流程说明

image-20220418150641199

  1. 执行bgsave命令,如果有存在正在执行的子进程,这直接返回
  2. 执行fork操作创建子进程,fork完成后父进程可以继续响应其他命令
  3. 子进程根据父进程内存生成临时快照文件,完成后替换原有RDB文件,通知父进程完成

AOF

AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中的命令达到恢复数据的目的。AOF的主要作用是解决了数据持久化的实时性

  • AOF 文件的内容是操作命令;

  • RDB 文件的内容是二进制数据。

工作流程

image-20220418151715491

1)所有的写人命令会追加到aof_buf(缓冲区)中。
2)AOF 缓冲区根据对应的策略向硬盘做同步操作。
3)随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的。
4)当Redis服务器重启时,可以加载AOF文件进行数据恢复。

文件同步策略

Redis提供了多种AOF 缓冲区同步文件策略,由参数appendfsync控制

  1. always

    命令写入aof_buf后调用系统fsync操作同步到AOF文件,fsync完成后线程返回

  2. everysec

    命令写人aof_buf后调用系统write操作,write完成操作后线程返回。fsync同步文件操作由专门线程每秒调用一次

  3. no

    命令写人aof_buf后调用系统write操作,不对AOF文件做fsync同步,同步硬盘操作由操作系统负责,通常同步周期最长30秒

系统调用write和fsync

调用wirte的时候,会将aof缓存区的文件先放入到内核缓存区中,然后再由fsync放入到硬盘中,所以调用wirte的本质还是调用fsync

image-20220418152439209

由此我们可知三种同步策略只是在控制fsync()函数的调用时机不同而已。

  • Always 策略就是每次写入 AOF 文件数据后,就执行 fsync() 函数;

  • Everysec 策略就会创建一个异步任务来执行 fsync() 函数;

  • No 策略就是永不执行 fsync() 函数;

重写机制

AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程

重写的aof文件为什么变小?

  1. 进程内已经超时的数据不再写人文件。

  2. 旧的AOF文件含有无效命令,比如del key1,重写使用进程内数据直接生成,只保留最终数据的写入命令

  3. 多条写命令可以合并为一个

工作流程

image-20220418153222820

  1. 执行AOF重写请求。
    如果当前进程正在执行AOF重写,请求不执行
  2. 父进程执行fork创建子进程来执行重写操作,fork完成后可以继续响应其他命令
  3. 由于fork操作运用写时复制技术,子进程只能共享fork操作时的内存数据。由于父进程依然响应命令,Redis使用“AOF重写缓冲区”保存这部分新数据,防止新AOF文件生成期间丢失这部分数据。
  4. 重写完成后,子进程发送信号给父进程,父进程把AOF重写缓存区写入到新的AOF文件中
  5. 将新AOF文件替换老文件

重启加载

image-20220418160735605

  1. AOF持久化开启且存在AOF文件时,优先加载AOF文件
  2. AOF关闭或者AOF文件不存在时,加载RDB文件
  3. 加载AOF/RDB文件成功后,Redis启动成功
  4. AOF/RDB文件存在错误时,Redis启动失败并打印错误信息

写时复制技术

在RDB的bgsave中跟AOF的重写中都用到了写时复制技术,它可以使得子进程在操作的过程中,当父进程需要修改数据时,不会互相影响。通过 fork() 创建子进程后,此时子进程和父进程是共享同一片内存数据的,因为创建子进程的时候,会复制父进程的页表,但是页表指向的物理内存还是一个。

image-20220418161128316

这样一来,子进程就共享了父进程的物理内存数据了,这样能够节约物理内存资源,页表对应的页表项的属性会标记该物理内存的权限为只读

不过,当父进程或者子进程在向这个内存发起写操作时,CPU 就会触发缺页中断,这个缺页中断是由于违反权限导致的,然后操作系统会在「缺页异常处理函数」里进行物理内存的复制,并重新设置其内存映射关系,将父子进程的内存读写权限设置为可读写,最后才会对内存进行写操作,这个过程被称为「写时复制 (Copy On Write)」。

image-20220418161115854

参考链接

宕机了,缓存数据没了。。。

0

评论区