参考书籍《Redis设计与实现》

一丶为什么redis需要持久化

redis 作为一个内存数据库,如果不想办法将存储在内存中的数据,保存到磁盘中,那么一旦服务器进程退出,那么redis数据库中的数据就将丢失。

二丶RDB

redis 提供RDB持久化功能,可以将数据库中的数据保存到磁盘中,避免数据意外丢失。Redis RDB 是将一个时间点的数据库状态保存到RDB文件中,RDB文件时一个经过压缩的二进制文件,通过该文件可以还原申生成RDB时的数据库状态。

1.SAVE与BGSAVE

SAVE和BGSAVE 命令都能生成RDB文件

  • SAVE命令会阻塞redis服务器进程,直到SAVE命令执行完为止,在服务器进程阻塞的期间,服务器无法处理任何命令请求
  • BGSAVE会派生出一个子进程,然后由子进程负责创建RDB文件,服务器进程可以继续处理请求命令

Redis 服务在启动的时候会检测RDB文件的存在,并自动载入RDB文件。由于AOF文件更新的频率比RDB高(频率高意味着数据全),所以如果同时具备AOF 和RDB文件,redis服务器会选择AOF文件进行恢复。

BGREWRITEAOF 可以触发AOF持久化,但是不允许和BGSAVE一起执行(因为一起执行意味着大量的磁盘写入操作)

2.RDB自动间隔保存

redis 允许用户通过配置save选项,让服务器每隔一段时间自动执行一次BGSAVE命令。如

save 900 1
save 300 10
save 60 1000

这个配置意味着,如果900秒内对数据库进行至少一次修改,300秒内对数据库至少由十次修改,60秒内有1000次修改,那么redis服务器将自动进行BGSAVE命令的执行。

为了实现这个功能redis服务器会记录两个内容:dirty(距离上一次成功执行save 或者bgsave 数据库进行了多少次修改)和 lastsave (时间戳,记录上一次执行save 或者 bgsave 的时间)。redis 周期性操作函数serverCron每隔100毫秒执行一次,会根据dirtylastsave是否满足 save 900 1等配置的要求,如果满足那么将执行BGSAVE

三丶AOF

除了RDB之外,redis 还有AOF(append only file)持久化的功能,与RDB持久化通过将数据库数据保存到文件中不同,AOF 持久化时通过保存redis服务器执行的修改操作命令来实现的。如

set msg "hello"

对于这条命令,RDB记录的是msg 键和对应的值,但是AOF记录的是set msg "hello"这条命令。AOF持久化可以使用BGREWRITEAOF触发

AOF可以分为如下流程

1.命令追加

服务器在执行完一个写明了后,会以协议格式将被执行的命令追加到redis服务器中的aof_buf末尾

2.AOF 文件写入和同步

redis每次结束一个事件循环之前都会调用flushAppendOnlyFile来判断是否需要将aof_buf里的内容写入到AOF文件中。redis服务器配置的appendfsync 设置可以控制aof 文件写入的时机:

  • always

    将aof缓冲区的所有内容写入并且同步到aof文件

    选择此配置,意味着每次都需要将命令写回磁盘,安全性最高,但是会导致效率很低

  • everysec

    每秒写入aof缓冲区中的内容,并同步aof文件(同步操作由另外一个线程专门进行)

    选择此配置,意味着每秒写回磁盘,最多丢失一秒的数据

  • no

    将aof缓冲区中的内容写入到AOF文件但是不同步,何时同步由操作系统决定

    此配置不会将命令马上写回磁盘,效率高,但是不安全

为了提高文件的写入效率,在现代操作系统中,用户调用write函数,将一些数据写入到文件的时候,操作系统通常会将期望写入的数据保存到一个内存缓冲区中,等缓冲区满或者超过一段事件后,才真正的将缓冲数据写入到磁盘
这样的操作提高的效率,但是带来了数据丢失的风险,所以操作系统提供了fsync 和fdatasync两个同步函数,让用户调用强制让缓冲区写入磁盘,从而确保数据的安全性

3.AOF重写

因为aof文件记录的是数据库执行的修改操作命令,这意味着随着时间的流逝,aof文件中的内容将越来越多。为了解决这个问题redis使用AOF重写——redis服务器可以创建一个新的aof文件来替代现有的aof文件,二者保存的数据库数据相同,但是新的文件不会保存冗余命令(set msg "a" 然后执行set msg "b" 其实aof文件只需要保存set msg "b" )

3.1 AOF 重写原理

AOF重写并不是分析已有文件,而是读取数据库中的数据,将数据转化为命令。首先读取数据库中的键和值,然后使用一条命令来记录键值对,这就是aof重写的实现原理(对于哈希,集合,有序集合,列表键值对,redis一条命令只会记录64个元素,超过64个元素,将使用多条命令记录)

3.2 AOF 后台重写

AOF重写程序将使用子进程的方式执行命令,从而让服务器进程可以继续处理请求。

为了解决重写过程中,键值对被修改的问题,redis使用aof重写缓冲区,在重写过程中,用户修改数据库的命令会被保存到AOF缓冲区和AOF重写缓冲区。子进程完成AOF重写后,会将AOF重写缓冲区中的命令同步到新AOF文件中,这时候新文件保存的内容就和数据库一致了。然后子进程将修改新AOF文件名称,原子的覆盖旧AOF文件。

Redis RDB 与AOF的更多相关文章

  1. 搞懂Redis RDB和AOF持久化及工作原理

    前言 因为Redis的数据都储存在内存中,当进程退出时,所有数据都将丢失.为了保证数据安全,Redis支持RDB和AOF两种持久化机制有效避免数据丢失问题.RDB可以看作在某一时刻Redis的快照(s ...

  2. redis RDB 和AOF

    参考文献 Redis源码学习-AOF数据持久化原理分析(0) Redis源码学习-AOF数据持久化原理分析(1) Redis · 特性分析 · AOF Rewrite 分析 深入剖析 redis AO ...

  3. redis持久化RDB和AOF

    Redis 持久化: 提供了多种不同级别的持久化方式:一种是RDB,另一种是AOF. RDB 持久化可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot). AO ...

  4. redis的 rdb 和 aof 持久化的区别 [转]

    aof,rdb是两种 redis持久化的机制.用于crash后,redis的恢复. rdb的特性如下: Code: fork一个进程,遍历hash table,利用copy on write,把整个d ...

  5. Redis提供的持久化机制(RDB和AOF)

    Redis提供的持久化机制 Redis是一种面向"key-value"类型数据的分布式NoSQL数据库系统,具有高性能.持久存储.适应高并发应用场景等优势.它虽然起步较晚,但发展却 ...

  6. redis的持久化 rdb和aof

    1.rdb(Redis DataBase) 当满足条件时,redis单独会fork(创建)一个新的线程,会先将内存中的数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次已经持久化 ...

  7. Redis持久化的两种方式(RDB和AOF)

    redis提供了两种持久化的方式,分别是RDB(Redis DataBase)和AOF(Append Only File). RDB,简而言之,就是在不同的时间点,将redis存储的数据生成快照并存储 ...

  8. 【Redis篇】Redis持久化方式AOF和RDB

    一.前述 持久化概念:将数据从掉电易失的内存存放到能够永久存储的设备上. Redis持久化方式RDB(Redis DB)   hdfs:    fsimageAOF(AppendOnlyFile)   ...

  9. redis的 rdb 和 aof 持久化的区别

    aof,rdb是两种 redis持久化的机制.用于crash后,redis的恢复. rdb的特性如下: Code: fork一个进程,遍历hash table,利用copy on write,把整个d ...

  10. Redis 持久化RDB 和AOF

    一.持久化之全量写入:RDB rdb配置 [redis@6381]$ more redis.conf save 900 1 save 300 10 save 60 10000 dbfilename & ...

随机推荐

  1. P3629 [APIO2010] 巡逻 (树的直径)

    (这道题考察了求直径的两种方法......) 在原图中,每条边要经过两次,增加1条后,形成了一个环,那么环上的边只需要经过一次了(大量画图分析得),再增加一条又会形成一个环,如果这两个环有重叠,重叠部 ...

  2. java中的自动拆装箱与缓存(Java核心技术阅读笔记)

    最近在读<深入理解java核心技术>,对于里面比较重要的知识点做一个记录! 众所周知,Java是一个面向对象的语言,而java中的基本数据类型却不是面向对象的!为了解决这个问题,Java为 ...

  3. day45-JDBC和连接池01

    JDBC和连接池01 1.JDBC概述 基本介绍 JDBC为访问不同的数据库提供了同一的接口,为使用者屏蔽了细节问题 Java程序员使用JDBC,可以连接任何提供了jdbc驱动程序的数据库系统,从而完 ...

  4. 基于tauri+vue3.x多开窗口|Tauri创建多窗体实践

    最近一种在捣鼓 Tauri 集成 Vue3 技术开发桌面端应用实践,tauri 实现创建多窗口,窗口之间通讯功能. 开始正文之前,先来了解下 tauri 结合 vue3.js 快速创建项目. taur ...

  5. Java 8 Time API

    Java 8 系列文章 持续更新中 日期时间API 也是Java 8重要的更新之一,Java从一开始就缺少一致的日期和时间方法,Java 8 Date Time API是Java核心API的一个非常好 ...

  6. Java基础面试总结

    常见编译型语言:C.C++.Go.Rust 等(执行速度快,但开发效率低) 常见解释型语言:Python.JavaScript.PHP(开发效率高,但执行效率低) 先编译后解释:Java 重载和重写有 ...

  7. 题解 CF630L Cracking the Code

    前言 为什么没有人暴力快速幂啊,Ta不香嘛/kel 题意 设读入为 \(abcde\) ,求 \(acedb^5\mod{10^5}\) 的结果. \(\sf {Solution}\) 显然暴力啊. ...

  8. 常用类.String类

    package 常用类.String;import java.util.Arrays;import java.util.Locale;public class demo01 { public stat ...

  9. while、for循环结合else

    """1.while else,当while循环正常结束时,才走else里的代码块,也就是没有被break打断的情况下2.此处只是不被break打断,也就是遇到break ...

  10. 使用 html2canvas 将页面中某一部分转为图片下载

    今天在项目中遇到一个需求是将生成的二维码和一些背景作为海报,然后将海报以图片的形式下载 使用了 html2canvas  插件 import html2canvas from "html2c ...