一文让你明白Redis持久化(RDB、AOF)

一文让你明白Redis持久化(RDB、AOF)

为什么要持久化

Redis是内存数据库,如果不将内存中的数据库状态保存到磁盘中,那么一旦服务器进程退出,服务器的数据库状态就会消失(即断电即失)。为了保证数据不丢失,我们需要将
内存中的数据存储到磁盘,以便 Redis 重启时能够从磁盘中恢复原有的数据,而整个过程就叫做 Redis 持久化。

Redis 持久化也是 Redis 和 Memcached 的主要区别之一,因为 Memcached 是不具备持久化功能的。

持久化的几种方式

Redis 持久化拥有以下三种方式:

快照方式(RDB, Redis DataBase)将某一个时刻的内存数据,以二进制的方式写入磁盘;

文件追加方式(AOF, Append Only File),记录所有的写操作命令,并以文本的形式追加到文件中;

混合持久化方式,Redis 4.0 之后新增的方式,混合持久化是结合了 RDB 和 AOF 的优点,在写入的时候,先把当前的数据以 RDB 的形式写入文件的开头,再将后续的操作命令

以 AOF 的格式存入文件,这样既能保证 Redis 重启时的速度,又能避免数据丢失的风险。

因为每种持久化方案,都有特定的使用场景,让我们先从 RDB 持久化说起吧。

一、什么是RDB,RDB如何实现持久化?

1、什么是RDB?

RDB是Redis Database 的缩写,其作用是在 某一个时间点,将Redis存储在内存中的数据生成快照并存储到磁盘等介质上,存在这个磁盘介质上的文件就是RDB文件。”快照”顾名

思义就是好像照相一样保存当时的数据,这里RDB文件是一个二进制的文件,并且是经过压缩的。因为RDB文件是保存在硬盘中的,即使Redis服务器进程退出,甚至运行Redis

服务器的计算机宕机,但只要RDB文件仍然存在,Redis服务器就可以用它来还原数据库状态。

2、触发方式(手动、自动)

RDB 的持久化触发方式有两类:一类是手动触发,另一类是自动触发。

1)手动触发(执行 save 或者 bgsave 命令)

手动触发持久化的操作有两个命令: save 和 bgsave ,它们主要区别体现在: 是否阻塞 Redis 主线程的执行

save命令

redis 127.0.0.1:6379> SAVE

在客户端中执行 save 命令,就会触发 Redis 的持久化,但同时也是使 Redis 处于阻塞状态,直到 RDB 持久化完成,才会响应其他客户端发来的命令,

所以在生产环境一定要慎用

一文让你明白Redis持久化(RDB、AOF)
bgsave命令
redis 127.0.0.1:6379> BGSAVE

bgsave(background save)既后台保存的意思, 它和 save 命令最大的区别就是 bgsave 会 fork() 一个子进程来执行持久化,整个过程中只有在 fork() 子进程时有短暂的

阻塞,当子进程被创建之后,Redis 的主进程就可以响应其他客户端的请求了,相对于整个流程都阻塞的 save 命令来说,显然 bgsave 命令更适合我们使用。

一文让你明白Redis持久化(RDB、AOF)

在快照进行的过程中,也就是生成文件的过程中,不会对原有的RDB文件进行修改,直到快照生成完毕,直接将老的替换成新的,保证rdb文件任何时刻都是完整的。

2) 自动触发

自动触发的含义就是不用我们手动命令去触发持久化,而是通过配置当满足某一规则的时候自动去执行 bgsave 命令。

Redis的配置文件就默认设置了3个保存点:

以下配置表示的条件:
900秒内有1个key发生了变化,则触发保存RDB文件
save 900 1
服务器在300秒之内被修改了10次
save 300 10
服务器在60秒之内被修改了10000次
save 60 10000

#如果想禁用快照保存的功能,可以通过注释掉所有"save"配置达到,或者在最后一条"save"配置后添加如下的配置:
save ""

注意这里满足条件执行的是 bgsave命令。

二、什么是AOF,AOF如何实现持久化?

1、什么是AOF?

以日志的形式来记录 每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,

换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作 。

默认情况下,redis是没有开启AOF(append only file)的。开启AOF功能需要设置配置:appendonly yes 。

2、AOF持久化流程

上面提到了AOF持久化的过程就是日志不断追加的过程,这里通过图 给大家介绍具体流程:

一文让你明白Redis持久化(RDB、AOF)

1、Client作为命令的来源,会有多个源头以及源源不断的请求命令。

2、在这些命令到达Redis Server 以后,并不是直接写入AOF文件,会将其这些命令先放入 AOF缓存中进行保存。这里的AOF缓冲区实际上是内存中的一片区域,存在的目

的是当这些命令达到一定量以后再写入磁盘,避免频繁的磁盘IO操作。

3、AOF缓冲会根据对应的 策略将命令写入磁盘上的AOF文件。

4、AOF文件随着写入文件内容的增加,会根据规则进行命令的合并,这里叫做 AOF重写,从而起到AOF文件压缩的目的。

5、当Redis Server 服务器重启的时候会从AOF文件载入数据。

这里面有两点需要在详细写: AOF缓冲区同步文件策略AOF重写机制

3、AOF缓冲区同步文件策略

上面提到了Redis 会将命令先写入到AOF缓冲区,再写入AOF文件。这里介绍一下AOF缓冲区同步文件的三个策略。

#aof持久化策略的配置
appendfsync always    #always表示每次写入都执行fsync,以保证数据同步到磁盘
appendfsync everysec   #everysec表示每秒执行一次fsync,可能会导致丢失这1s数据
appendfsync no   #no表示不执行fsync,由操作系统保证数据同步到磁盘,速度最快

Always策略 的同步操作是在主进程的主线程中进行的,由于fsync的阻塞特性,会导致其挂起,在此期间无法服务新的请求,因而吞吐量下降,但确实能够保证内存和硬盘中

数据的一致性。

Everysec策略 的同步操作是通过后台I/O线程进行的,由于是在子线程中进行,所以主线程并不会被阻塞,可以继续服务新的请求,但是内存和硬盘中的数据会有1秒的差别

(不一定精准),这是一种折衷的方案,寻求了一个平衡。

No策略 则是将同步操作的控制权交由操作系统,不阻塞主线程,但是数据一致性可能会偏差很大

官方建议使用默认配置每秒同步,它既快速又安全。这个always策略在实践中非常缓慢, 没有办法做得fsync比现在更快。

4、AOF重写机制

(1)是什么?

AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩, 只保留可以恢复

数据的最小指令集。

举个例子:比如有个key 一开始你 set key 1,然后改成 set key 2,最后 set key 3。如果不重写那么这3条语句都在文件中,这样即占空间,启动的时候都要执行一遍无效

的命令,如果重写后,只需要保存set key 3 就可以了。

AOF重写不仅降低了文件的占用空间,同时更小的AOF也可以更快地被Redis加载。

(2)触发机制(手动、自动)

手动:客户端向服务器发送bgrewriteaof命令

自动:满足配置文件中的选项后,自动执行bgrewriteaof命令。Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时

触发。

(3)重写原理

AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),遍历新进程的内存中数据,每条记录有一条的Set语句。重写aof文件的操作,

并没有读取旧的aof文件, 而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件,这点和快照有点类似。

三、RDB和AOF各自优缺点

1、RDB的优点

(1)比起AOF,在数据量比较大的情况下,RDB的启动速度更快。

(2)RDB文件是一个很简洁的单文件,它保存了某个时间点的Redis数据,很适合用于做备份。

(3)RDB的性能很好,需要进行持久化时,主进程会fork一个子进程出来,然后把持久化的工作交给子进程,自己不会有相关的I/O操作。

2、RDB缺点

(1)RDB容易造成数据的丢失。假设每5分钟保存一次快照,如果Redis因为某些原因不能正常工作,那么从上次产生快照到Redis出现问题这段时间的数据就会丢失了。

(2)RDB使用fork()产生子进程的过程会堵塞主进程,所以数据比较大的话 fork() 可能很耗时,就会造成Redis停止服务几毫秒。

3、AOF优点

(1)该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常

高的,如果发生灾难,您只可能会丢失1秒的数据。

(2)AOF日志文件是一个纯追加的文件。就算服务器突然Crash,也不会出现日志的定位或者损坏问题。甚至如果因为某些原因(例如磁盘满了)命令只写了一半到日志文件里,

我们也可以用redis-check-aof这个工具很简单的进行修复。

(3)当AOF文件太大时,Redis会自动在后台进行重写。重写很安全,因为重写是在一个新的文件上进行。

4、AOF缺点

(1)在相同的数据集下,AOF文件的大小一般会比RDB文件大。

(2)AOF开启后,写QPS会比RDB的低。通常fsync设置为每秒一次就能获得比较高的性能,而在禁止fsync的情况下速度可以达到RDB的水平。

四、生产配置持久化的一些意见

(1)官方建议:是同时开启两种持久化策略。因为有时需要RDB快照是进行数据库备份,更快重启以及发生AOF引擎错误的解决办法。(换句话就是通过RDB来多备份一份数据

总是好的)

(2) 因为RDB文件只用作后备用途,建议只在Slave上持久化RDB文件,而且只要15分钟备份一次就够了,只保留save 900 1这条规则。

(3)如果选择AOF,只要硬盘许可,应该尽量减少AOF rewrite的频率。因为一是带来了持续的IO,二是AOF rewrite的最后将rewrite过程中产生的新数据写到新文件造成的阻塞

几乎是不可避免的。AOF重写的基础大小默认值64M太小了,可以设到2G以上。

声明: 公众号如需转载该篇文章,发表文章的头部一定要 告知是转至公众号: 后端元宇宙。同时也可以问本人要markdown原稿和原图片。其它情况一律禁止转载!

一文让你明白Redis持久化(RDB、AOF)

Original: https://www.cnblogs.com/qdhxhz/p/15684650.html
Author: 雨点的名字
Title: 一文让你明白Redis持久化(RDB、AOF)

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/528964/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 2021年想做的最后挣扎

    一年的时间转眼间就过完,感觉没变,又感觉跟一年前的今天变化还是蛮多的,树立个小目标争取年前完成把 读书一本书看一篇文章: 《百年孤独》:我总感觉虽然是只单身狗是孤单的,理解不了孤独…

    Linux 2023年6月14日
    0103
  • OrchardCore Headless建站拾遗

    书接上回,OrchardCore的基本设置写了,但是有一说一,这个东西还是挺复杂的,如果需要构建一个简单的企业网站,还需要干点别的活。 本文考虑在尽量少编程的基础上,完成一个Hea…

    Linux 2023年6月6日
    0107
  • python 练习题:将列表中的大写字母转换成小写

    将列表中的大写字母转换成小写如果list中既包含字符串,又包含整数,由于非字符串类型没有lower()方法,L1 = [‘Hello’, ‘World’, 18, ‘Apple’,…

    Linux 2023年6月8日
    0149
  • batch批处理笔记

    1. echo 和 @ 回显命令 @ #关闭单行回显 echo off #从下一行开始关闭回显 @echo off #从本行开始关闭回显。一般批处理第一行都是这个 echo on …

    Linux 2023年6月7日
    094
  • 一文教你快速部署OneBlog开源项目

    镜像下载、域名解析、时间同步请点击阿里云开源镜像站 OneBlog是什么? OneBlog,一个简洁美观、功能强大并且自适应的Java博客。使用springboot开发,前端使用B…

    Linux 2023年5月27日
    0126
  • 玩转redis-延时消息队列

    上一篇基于 redis的list实现了一个简单的消息队列:玩转redis-简单消息队列 源码地址 使用demo 产品经理经常说的一句话,我们不光要有 X功能,还要 Y功能,这样客户…

    Linux 2023年5月28日
    0137
  • 将Java代码打包成jar文件转换为.exe可执行程序方法

    ​ 做完学生管理系统后我想将代码打包成一个可执行程序,那样就可以直接点击在Windows下运行了,下面就跟大家分享下打包方法。 将Java的代码转换成 .exe 文件需要先把代码打…

    Linux 2023年6月6日
    0105
  • Struts2-045漏洞

    前言 Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个servlet,在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图…

    Linux 2023年6月14日
    0108
  • Grafana+Prometheus 搭建 JuiceFS 可视化监控系统

    作为承载海量数据存储的分布式文件系统,用户通常需要直观地了解整个系统的容量、文件数量、CPU 负载、磁盘 IO、缓存等指标的变化。 JuiceFS 没有重复造轮子,而是通过 Pro…

    Linux 2023年6月14日
    097
  • jmeter 安装与环境变量配置

    安装jmeter首先要安装与jmeter版本兼容的JDK,安装完成JDK后才能安装jmeter,JDK可以自行在官网下载或者通过360软件管家进行下载。 1、下载安装JDK 安装完…

    Linux 2023年6月8日
    099
  • IDEA版本与MAVEN版本对应关系,及历史MAVEN版本下载【转】

    1、查看自己的IDEA版本 Help -> About 3、下载指定版本MAVEN Original: https://www.cnblogs.com/fb010001/p/…

    Linux 2023年6月8日
    0107
  • centos7用rpm安装mysql5.7【初始用yum安装发现下载非常慢,就考虑本地用迅雷下载rpm方式安装】

    1.下载 4个rpm包 mysql-community-client-5.7.26-1.el7.x86_64.rpmmysql-community-common-5.7.26-1….

    Linux 2023年6月7日
    0105
  • Linux 查看端口被占用

    端口被占用网上很多,这种频繁操作的命令容易忘记,写这边文章的目的主要是加深操作命令的印象, Liux 查看端口占用情况可以使用 lsof 和 netstat 命令。 lsof ls…

    Linux 2023年6月6日
    094
  • sftp配置

    有很多方法,可实现在网络上分享文件。其中之一为FTP协议。但FTP通过明文传输数据,不安全。幸运的是,SSH协议族中包含了用于传输文件的SFTP协议。 事实上,任何远程主机的用户,…

    Linux 2023年6月14日
    0119
  • shell中的##*,%%*问题

    假设我们定义了一个变量为:file=/dir1/dir2/dir3/my.file.txt 可以用${ }分别替换得到不同的值:${file#/}:删掉第一个 / 及其左边的字符串…

    Linux 2023年5月28日
    078
  • 预处理

    在前面的学习中经常遇到用 #define命令定义符号常量的情况,其实使用 #define命令就是要定义一个可替换的宏。 宏定义是预处理命令的一种,它提供了一种可以替换源代码中字符串…

    Linux 2023年6月13日
    097
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球