【数据库】redis数据持久化

news/2024/4/19 14:47:24/文章来源:https://blog.csdn.net/weixin_48814356/article/details/129164857

目录

数据持久化

一, RDB

1, 什么是RDB

2,持久化流程

3, 相关配置

案例演示:

4, 备份和恢复

1、备份

2、恢复

3,优势

4, 劣势

二,AOF

1,什么是AOF

2, 持久化流程

3, 使用AOF

1、开启AOF

2、使用演示

3、备份

4、恢复

5、异常恢复

4, Rewrite压缩

1,Rewrite是什么

2、重写原理与流程

3, 优势

4, 劣势

5,选择AOF还是RDB


数据持久化

Redis提供了主要提供了 2 种不同形式的持久化方式:

  • RDB(Redis数据库):RDB 持久性以指定的时间间隔执行数据集的时间点快照。
  • AOF(Append Only File):AOF 持久化记录服务器接收到的每个写操作,在服务器启动时再次播放,重建原始数据集。 命令使用与 Redis 协议本身相同的以仅追加的格式记录。 当日志变得太大时,Redis 能够在后台重写日志。

 

一, RDB

1, 什么是RDB

在指定的时间间隔内将内存中的数据集快照写入磁盘, 也就是Snapshot快照,它恢复时是将快照文件直接读到内存里。正是这种特性,让我们可以随时来进行备份,因为快照文件总是完整可用的。RDB是redis默认的持久化策略。

 

2,持久化流程

启动持久化后:

(1)检查是否存在子进程正在执行 AOF 或者 RDB 的持久化任务。如果有则返回 false。

(2)调用 Redis 源码中的 rdbSaveBackground 方法,方法中执行 fork() 产生子进程执行 RDB 操作。也就是说Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束后,再用这个临时文件替换上次持久化好的文件。 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。

Fork 的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等) 数值都和原进程一致,但它是一个全新的进程,并作为原进程的子进程。

在 Linux 程序中,fork() 会产生一个和父进程完全相同的子进程,但子进程在此后可能会执行 exec 系统调用,出于效率考虑,Linux 中引入了“写时复制技术”。一般情况下父进程和子进程会共用同一段物理内存,只有进程空间的各段的内容要发生变化时,才会将父进程的内容复制一份给子进程。

虽然RDB有不少优点,但它的缺点也是不容忽视的。如果你对数据的完整性非常敏感,那么RDB方式就不太适合你,因为即使你每5分钟都持久化一次,当redis故障时,仍然会有近5分钟的数据丢失。所以,redis还提供了另一种持久化方式,那就是AOF。

 

3, 相关配置

 redis创建RDB文件的方式:

  • 手动执行SAVE
  • 优点:节约系统资源。
  • 缺点:直接调用rdbSave ,阻塞Redis主进程,直到保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任何请求。
  • 手动执行BGSAVE
  • 优点:fork 出一个子进程,子进程负责调用 rdbSave ,并在保存完成之后向主进程发送信号,通知保存已完成。 Redis 服务器在BGSAVE 执行期间仍然可以继续处理客户端的请求。
  • 缺点:由于会fork一个进程,因此更消耗内存。
  • 满足配置条件进行rdb持久化。
    快照持久化是Redis中默认开启的持久化方案,根据redis.conf中的配置设置一些默认参数。

 

 

读取redis的配置文件redis.conf。

1、快照将被写入dbfilename指定的文件中(默认是dump.rdb文件)。

dbfilename dump.rdb

 

2、快照将保存在dir选项指定的路径上,我们可以修改为指定目录,建议使用绝对路径,如果使用相对路径,则会根据执行命令所在目录来生成dump.rdb文件。

dir /var/lib/redis

 

3、可以使用单个空字符串参数完全禁用快照。

save ""

4、在3600s内如果有1条数据被写入,则执行bgsave选项,产生一次快照

 save 3600 1

在300s内如果有100条数据被写入,则执行bgsave选项,产生一次快照

save 300 100

在60s内如果有10000条数据被写入,则执行bgsave选项,产生一次快照

 save 60 10000

5、该指令用于指定是否开启当做快照时发生错误停止服务器写入数据;默认是yes,表示开启当做快照时发生错误而停止redis服务器的写入;

stop-writes-on-bgsave-error yes

6、对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,Redis 会采用 LZF 算法进行压缩。如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能。推荐配置为 yes。

rdbcompression yes

7、在存储快照后,还可以让 Redis 使用 CRC64 算法来进行数据校验,检查数据完整性。但是这样做会增加大约 10% 的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。推荐配置为 yes。

rdbchecksum yes

 

 

 

 

案例演示:

1,在配置文件中设置30秒内写入5条数据就产生一次快照,也就是生成 rdb 文件

Save 30 5

修改完配置文件需要重启服务

systemctl restart redis

 

2,在/var/lib/redis目录下面查看文件dump.rdb,此时文件大小为854

cd /var/lib/redisll

3,输入5条记录

(1)执行前四条指令,文件大小并没有改变

(2)执行5条指令,发现文件大小变大了,

4,也可以通过查看日志的方法

(1)输入5次

(2)日志文件更新

可以通过查看 dump.rdb 文件的大小,就可以发现文件快照已经产生了。

如果输入6 条数据,是否都持久化了?

只持久化了前 5 条数据,最后 1 条数据没有持久化。

4, 备份和恢复

1、备份

(1)首先执行如下命令来清空数据:

flushdb

ll

 

(2)然后再重新添加如下数据:

set k1 v1set k2 v2set k3 v3set k4 v4set k5 v5set k6 v6

 

 

 

(3)备份 dump.rdb,备份文件名为dump.rdb.back

cp dump.rdb dump.rdb.back

 

 

(4)最后把 Redis 服务关闭

systemctl stop redis

 

(5)然后把 dump.rdb 文件删除

rm -f dump.rdb

 

 

 

2、恢复

(1)首先执行如下命令来把 dump.rdb.back 文件修改为 dump.rdb。

mv dump.rdb.back dump.rdb

 

(2)恢复后所属者与所属组为root,若继续持续化,强制转化为redis

备份和还原时可以使用-a选项来保留所有属性

 

 

(3)然后重启 Redis 服务

systemctl restart redis

 

 

(4)然后连接客户端后再执行如下命令来查看:

keys *

 

 

 

3,优势

RDB 方式适合大规模的数据恢复,并且对数据完整性和一致性要求不高更适合使用。它有以下几种优势:

  • 节省磁盘空间
  • 恢复速度快

 

 

4, 劣势

  • Fork的时候,内存中的数据被克隆了一份,导致2倍的膨胀性需要考虑
  • 虽然Redis在fork时使用了写时拷贝技术,但是如果数据庞大时还是比较消耗性能。
  • 备份周期是在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改。

 

二,AOF

1,什么是AOF

以日志的形式来记录每个写操作(增量保存),将Redis执行过的所有写指令记录下来(读操作不记录), 只追加文件但不可以改写文件,Redis启动之初会读取该文件重新构建数据。简单说,Redis 重启时会根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作。

在Redis的默认配置中AOF(Append Only File)持久化机制是没有开启的,要想使用AOF持久化需要先开启此功能。AOF持久化会将被执行的写命令写到AOF文件末尾,以此来记录数据发生的变化,因此只要Redis从头到尾执行一次AOF文件所包含的所有写命令,就可以恢复AOF文件记录的数据集。

 

2, 持久化流程

1)客户端的请求写命令会被 append 追加到 AOF 缓冲区内。

2)AOF 缓冲区根据 AOF 持久化策略 [always,everysec,no] 将操作sync同步到磁盘的 AOF 文件中。

3)AOF 文件大小超过重写策略或手动重写时,会对 AOF 文件 rewrite 重写,压缩 AOF 文件容量。

4)Redis 服务重启时,会重新 load 加载 AOF 文件中的写操作达到数据恢复的目的。

 

 

3, 使用AOF

1、开启AOF

#修改 redis.conf 配置文件

(1)AOF持久化是否开启

appendonly no

(2)指定日志文件名

appendfilename "appendonly.aof"

(3)通过appendfsync指定日志记录频率

# appendfsync always

appendfsync everysec

# appendfsync no

  • always选项,每个redis写命令都会被写入AOF文件中,并完成磁盘同步,好处是当发生系统崩溃时数据丢失减至最少,缺点是这种策略会产生大量的I/O操作,会严重降低服务器的性能。
  • everysec选项,以每秒一次的频率对AOF文件进行同步,并完成磁盘同步,可以保证系统崩溃时只会丢失一秒左右的数据,并且 Redis 每秒执行一次同步对服务器几乎没有任何影响。
  • no选项,写入aof文件,不等待磁盘同步。完全由操作系统决定什么时候同步AOF日志文件,这个选项不能给服务器性能带来多大的提升,反而会增加系统崩溃时数据丢失的数量。

 

2、使用演示

(1)修改redis.conf文件,开启AOF持久化

 vim /etc/redis/redis.conf

appendonly yes

(2)重启服务

systemctl restart redis

(3)查找文件 appendonly.aof的路径

 find / -name appendonly.aof

(4)appendonly.aof文件在/var/lib/redis,此时大小为0个字节

(5)默认读取AOF文件,AOF文件不存在才读取RDB文件

说明:发现没有任何数据。这说明:如果 RDB 和 AOF 文件同时存在,Redis 默认使用的是 AOF 文件。

3、备份

AOF的备份机制和性能虽然和RDB不同,但是备份和恢复的操作同RDB一样:都是拷贝备份文件,需要恢复时再拷贝到Redis工作目录下,启动系统即加载。

 

此时,appendonly.aof文件中有下面两个数据

 

 

 

(1)备份appendonly.aof文件

cp -a appendonly.aof appendonly.aof.back

 

 

(2)关闭redis服务

systemctl stop redis

 

 

(3)删除appendonly.aof文件

rm -f appendonly.aof

 

 

4、恢复

(1)恢复appendonly.aof文件

cp -a appendonly.aof.back appendonly.aof

 

(2)重启reids服务

systemctl restart redis

 

 

(3)重新连接服务,并查询所有数据

 

 

5、异常恢复

如遇到 AOF 文件被损坏,可以通过 /usr/local/bin/redis-check-aof --fix appendonly.aof 进行恢复。

 

(1)我们人为的在 appendonly.aof 中添加一点内容,假设文件损坏

在文件最后添加

vim appendonly.aof

redis-aof

(2)重启服务,重启失败

systemctl restart redis

(3)访问redis服务也失败

redis-cli

(4)对appendonly.aof文件进行修复

redis-check-aof --fix appendonly.aof

查看修复后的文件

cat appendonly.aof

(5)重启服务

systemctl restart redis

 

(6)重新连接服务

redis-cli

查看数据

4, Rewrite压缩

1,Rewrite是什么

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

 

2、重写原理与流程

AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再 rename),redis 4.0 版本后的重写,就是把rdb 的快照,以二进制的形式附在新的aof头部作为已有的历史数据,替换掉原来的流水账操作。

重写AOF文件具体流程:

1)手动执行bgrewriteaof命令或者自动触发重写,判断当前是否有bgsave或bgrewriteaof在运行,如果有,则等待该命令结束后再继续执行。

2)主进程fork出子进程执行重写操作,保证主进程不会阻塞。

3)子进程遍历redis内存中数据到临时文件,客户端的写请求同时写入aof_buf缓冲区和aof_rewrite_buf重写缓冲区保证原AOF文件完整以及新AOF文件生成期间的新的数据修改动作不会丢失。

4)子进程写完新的AOF文件后,向主进程发信号,父进程更新统计信息。主进程把aof_rewrite_buf中的数据写入到新的AOF文件。

5)使用新的AOF文件覆盖旧的AOF文件,完成AOF重写。

现在问题出现了,同时在执行bgrewriteaof操作和主进程写aof文件的操作,两者都会操作磁盘,而bgrewriteaof往往会涉及大量磁盘操作,这样就会造成主进程在写aof文件的时候出现阻塞的情形。

通过设置配置文件中参数no-appendfsync-on-rewrite=yes,表示不写入aof文件只写入缓存,并没有执行磁盘操作,只是写入了缓冲区,因此这样用户请求不会阻塞(因为没有竞争磁盘),但是在这段时间如果宕机会丢失这段时间的缓存数据。这样做可以提高性能,降低了数据安全性。

 

如果 no-appendfsync-on-rewrite=no,还是会把数据往磁盘里刷,但是遇到重写操作,可能会发生阻塞。这样做可以数据安全,但是性能降低。

因此,如果应用系统无法忍受延迟,而可以容忍少量的数据丢失,则设置为yes。如果应用系统无法忍受数据丢失,则设置为no。

重写虽然可以节约大量磁盘空间,减少恢复时间。但是每次重写还是有一定的负担的,因此设定Redis要满足一定条件才会进行重写。

 

auto-aof-rewrite-percentage 100:设置重写的基准值,表示当前aof文件增长占用空间和上一次重写后aof文件空间的比值。

auto-aof-rewrite-min-size 64mb:设置重写的基准值,最小文件64MB。达到这个值开始重写。

 

因为假设本身aof文件就很小的话,如果增长达到相应比值就要重写的话,重写会很频繁,所以redis重写条件为:系统载入时或者上次重写完毕时,Redis会记录此时AOF大小,设为base_size,如果Redis的AOF当前大小>= base_size +base_size*100% (默认)且当前大小>=64mb(默认)的情况下,Redis会对AOF进行重写。

例如:文件达到70MB开始重写,降到50MB,下次什么时候开始重写?

答:100MB

[root@mysql8-0-30 redis]# redis-cli

127.0.0.1:6379> info persistence

aof_current_size:118

aof_base_size:118

也可以手动重写

3, 优势

  • 备份机制更稳健,丢失数据概率更低,就算发生故障停机,也最多只会丢失一秒钟的数据。
  • 可读的日志文本,即使日志因为某些原因而包含了未写入完整的命令,redis-check-aof工具也可以轻易地修复这种问题。

4, 劣势

  • 比起RDB占用更多的磁盘空间。
  • 恢复备份速度要慢。
  • 存在个别Bug,因为个别命令的原因,导致AOF文件在重新载入时,无法将数据集恢复成保存时的原样。

 

5,选择AOF还是RDB

那么,在开发中是选择 RDB 还是选择 AOF 来持久化呢?

官网建议如下:

Ok, so what should I use?

The general indication you should use both persistence methods is if you want a degree of data safety comparable to what PostgreSQL can provide you.

If you care a lot about your data, but still can live with a few minutes of data loss in case of disasters, you can simply use RDB alone.

There are many users using AOF alone, but we discourage it since to have an RDB snapshot from time to time is a great idea for doing database backups, for faster restarts, and in the event of bugs in the AOF engine.

The following sections will illustrate a few more details about the two persistence models.

  • RDB持久化方式能够在指定的时间间隔对你的数据进行快照存储。
  • AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF持久化方式追加保存每次写的操作到文件末尾。
  • Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大。
  • 只做缓存:如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式。
  • 同时开启两种持久化方式:在这种情况下,当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。
  • RDB的数据不实时,同时使用两者时服务器重启也只会找AOF文件。那要不要只使用AOF呢? 建议不要,因为RDB更适合用于备份数据库(AOF在不断变化不好备份),而且不会有AOF可能潜在的bug,并且数据恢复更快,留着作为一个万一的手段。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_72644.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

说说 React 中 fiber、DOM、ReactElement、实例对象之间的引用关系

原生组件 fiber 原生组件 fiber,指的就是 type 为 “span”、“div” 的 fiber。 1.fiber.stateNode 指向真实 DOM 节点;2.node["__reactFiber$" randomKey] 指向对应 fiber,使用随机数是防止和业务代码的属性名冲突,…

Scala模式匹配详解(第八章:基本语法、模式守卫、模式匹配类型)(尚硅谷笔记)

模式匹配第 8 章 模式匹配8.1 基本语法8.2 模式守卫8.3 模式匹配类型8.3.1 匹配常量8.3.2 匹配类型8.3.3 匹配数组8.3.4 匹配列表8.3.5 匹配元组8.3.6 匹配对象及样例类8.4 变量声明中的模式匹配8.5 for 表达式中的模式匹配8.6 偏函数中的模式匹配(了解)第 8 章 模式匹配 Scal…

论文解读 | [AAAI2020] 你所需要的是边界:走向任意形状的文本定位

目录 1、研究背景 2、研究的目的 3、方法论 3.1 Boundary Point Detection Network(BPDN) 3.2 Recognition Network 3.3 Loss Functions 4、实验及结果 论文连接:https://ojs.aaai.org/index.php/AAAI/article/view/6896 1、研究背景 最近,旨在…

深度解读 | 数据资产管理面临诸多挑战,做好这5个措施是关键

日前,大数据技术标准推进委员会(中国通信标准化协会下(CCSA)的专业技术委员会,简称TC601)发布《数据资产管理实践白皮书》(6.0 版)(以下简称:报告&#xff09…

浏览器跨域问题

跨域问题什么是跨域问题如何解决跨域问题JSONPCORS方式解决跨域使用 Nginx 反向代理使用 WebSocket跨源请求是否能携带Cookie什么是跨域问题 跨域问题指的是不同站点之间,使用 ajax 无法相互调用的问题。跨域问题本质是浏览器的一种保护机制,它的初衷是为…

LQB01位操作说明

一个字节,包括了8位,可以对其中的8位的某一位进行读或者写; 比如char num12,如果用十六进制表示,就是0x0C,如果二进制表示,就是0000 1010 位操作函数,主要这里介绍,位读和位写0&am…

【消费战略方法论】认识消费者的恒常原理(一):消费者稳态平衡原理

“消费战略”是塔望咨询基于大量的战略与营销实践经验结合心理学、经济学、传播学等相关专业学科的知识应用进行提炼与创造形成的战略方法体系。消费战略强调以消费者为导向,进行企业、品牌战略、品牌营销的制订和落地,企业经营的每个环节和输出的每个动…

轻松搭建Redis缓存高可用集群

1. 安装单机Redis 安装步骤: 1.1 下载redis 官网下载3.0.0版本,之前几的版本不支持集群模式 下载地址:http://download.redis.io/releases/redis-3.0.0.tar.gz 1.2 首先需要安装gcc yum install gcc 1.3 创建目录 cd /usr/mkdir soft1.…

GitHub标星30K+的Java面试八股文长啥样?

2023年的互联网行业竞争越来越严峻,面试也是越来越难,一直以来我都想整理一套完美的面试宝典,奈何难抽出时间,这套1000道的Java面试手册我整理了整整1个月,上传到Git上目前star数达到了30K 一、32 道 MySQL 面试题 1&…

DACS: Domain Adaptation via Cross-domain Mixed Sampling 学习笔记

DACS介绍方法Naive MixingDACSClassMix![在这里插入图片描述](https://img-blog.csdnimg.cn/ca4f83a2711e49f3b754ca90d774cd50.png)算法流程实验结果反思介绍 近年来,基于卷积神经网络的语义分割模型在众多应用中表现出了显著的性能。然而当应用于新的领域时&…

乐友商城学习笔记(一)

SpringCloud 什么是SpringCloud 在SpringBoot基础上构建的微服务框架固定步骤 1.引入组件的启动器2.覆盖默认配置3.在引导类上添加相应的注解 eureka 注册中心,服务的注册与发现服务端 1.引入服务器启动器:eureka-server2.添加了配置 spring.applicati…

leetcode 21~30 学习经历

leetcode 21~30 学习经历21. 合并两个有序链表22. 括号生成23. 合并K个升序链表24. 两两交换链表中的节点25. K 个一组翻转链表26. 删除有序数组中的重复项27. 移除元素28. 找出字符串中第一个匹配项的下标29. 两数相除30. 串联所有单词的子串小结21. 合并两个有序链表 将两个升…

opencv-StereoBM算法流程(二)

OpenCV BM对于处理非畸变的立体图像, 主要有以下 3 个步骤:1. 预处理滤波: 使图像亮度归一化并加强图像纹理2. 立体匹配: 沿着水平极线用 SAD 窗口进行匹配搜索3. 再滤波: 去除坏的匹配点.匹配之后, 如果左右视差检查使能了 disp12MaxDiff > 0, 还有使用cv::validateDispari…

复习知识点三:做人不能半途而废,就算躺平也要躺最舒服的那张床

目录 运算符​编辑 键盘录入: 练习:键盘输入数字并求和 练习: 算术运算符 隐式转换(自动类型提升) 强制转换 练习1: 字符串的 "" 操作 ​编辑 练习 1: 练习2: 练习3: 自增自减运算符 赋值运算符 关系运算符(比较运算符)的分类 练习: 逻辑运算符 短路逻辑运…

qt qchart学习

Qt Charts主要由QChartView、QChart、QLegend图例、坐标轴(由QAbstractAxis子类实现)、**数据源(由QAbstractSeries子类实现)**等组成使用QChart的前期准备1. Qt5.9及以上版本;2. .pro文件中添加QT charts3. 在使用QChart的各个控件之前,引用头文件并必…

Vulnhub靶场----4、DC-4

文章目录一、环境搭建二、渗透流程三、思路总结一、环境搭建 DC-4下载地址:https://download.vulnhub.com/dc/DC-4.zip kali:192.168.144.148 DC-4:192.168.144.152 二、渗透流程 端口扫描:nmap -T5 -p- -sV -sT -A 192.168.144.1…

OSI模型和网络协议简介

文章目录一、OSI七层模型1.1什么是OSI七层模型?1.2这个网络模型究竟是干什么呢?二、TCP/IP协议三、常见协议四、物联网通信协议以及MQTT4.1 物联网七大通信协议4.2 MQTT特性一、OSI七层模型 1.1什么是OSI七层模型? 我们需要了解互联网的本质…

MySQL进阶篇之MySQL索引

今天主要学习MySQL索引,不过主要是使用Linux系统使用MySQL,主要是先在Linux环境下按照MySQL,然后演示索引的相关操作,介绍了索引的底层结构,索引的分类及语法,索引的性能分析,索引的使用规则&am…

《爆肝整理》保姆级系列教程python接口自动化(二十一)--unittest简介(详解)

简介 前边的随笔主要介绍的requests模块的有关知识个内容,接下来看一下python的单元测试框架unittest。熟悉 或者了解java 的小伙伴应该都清楚常见的单元测试框架 Junit 和 TestNG,这个招聘的需求上也是经常见到的。python 里面也有单元 测试框架-unitt…

数据结构_ 堆结构与堆排序(c++ 实现 + 完整代码 )

堆结构与堆排序 文章目录堆结构与堆排序引入堆堆结构所满足的数学特性准备代码----------- 往堆中插入元素----------- 删除堆顶堆排序构建完整代码及测试动态分配版本非动态版本引入堆 二叉树 具有左孩子与右孩子的最普通的二叉树。 满二叉树 特殊的二叉树:每个节…