0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

如何开启RDB持久化方式

马哥Linux运维 来源:马哥Linux运维 2023-06-25 11:52 次阅读

RDB快照(Redis DataBase)

RDB是一种快照存储持久化方式,具体就是将Redis某一时刻的内存数据保存到硬盘的文件当中,默认保存的文件名为dump.rdb,而在Redis服务器启动时,会重新加载dump.rdb文件的数据到内存当中恢复数据。

开启RDB持久化方式

开启RDB持久化方式很简单,客户端可以通过向Redis服务器发送save或bgsave命令让服务器生成rdb文件,或者通过服务器配置文件指定触发RDB条件。每次执行都会将所有redis内存快照到一个新的rdb文件里,并覆盖原有rdb快照文件。

方式一:save命令

#同步数据到磁盘上
>save
8086b58c-126e-11ee-962d-dac502259ad0.png

当客户端向服务器发送save命令请求进行持久化时,服务器会阻塞save命令之后的其他客户端的请求,直到数据同步完成。如果数据量太大,同步数据会执行很久,而这期间Redis服务器也无法接收其他请求,所以,最好不要在生产环境使用save命令。

方式二:bgsave命令

#异步保存数据集到磁盘上
>bgsave
80b666b0-126e-11ee-962d-dac502259ad0.png

当客户端发服务发出bgsave命令时,Redis服务器主进程会forks一个子进程来解决数据同步问题,在将数据保存到rdb文件之后,子进程会退出。

所以,与save命令相比,Redis服务器在处理bgsave采用子线程进行IO写入,而主进程仍然可以接收其他请求,但forks子进程是同步的,所以forks子进程时,一样不能接收其他请求,这意味着,如果forks一个子进程花费的时间太久(一般是很快的),bgsave命令仍然有阻塞其他客户的请求的情况发生。

我们可以控制单个Redis实例的最大内存,来尽可能降低Redis在fork时的事件消耗。以及上面提到的自动触发的频率减少fork次数,或者使用手动触发,根据自己的机制来完成持久化。

方式三:通过配置文件自动触发

自动触发的场景主要是有以下几点:

1.根据我们的 save m n 配置规则自动触发;

2.从节点全量复制时,主节点发送rdb文件给从节点完成复制操作,主节点会触发 bgsave;

3.执行 debug reload 时;

4.执行shutdown时,如果没有开启aof,也会触发。

这里我们讲的是根据配置文件自动触发:

#时间策略
#关闭RDB只需要将所有的save保存策略注释掉即可
save9001#900s内如果有1条数据写入,就产生RDB快照
save30010#300s内有10条数据写入,就产生RDB快照
save6010000#60s内如果有10000条数据写入,就产生RDB快照

#文件名称
dbfilenamedump.rdb

#文件保存路径
dir/var/lib/redis/6379

#如果持久化出错,主进程是否停止写入
stop-writes-on-bgsave-erroryes

#是否压缩
#建议没有必要开启,毕竟Redis本身就属于CPU密集型服务器,再开启压缩会带来更多的CPU消耗,相比硬盘成本,CPU更值钱。
rdbcompressionno

#导入时是否检查
rdbchecksumyes

save和bgsave对比

80eb5b54-126e-11ee-962d-dac502259ad0.png

配置文件自动生成rdb文件后台使用的是bgsave方式。

RDB文件

前面介绍了三种让服务器生成rdb文件的方式,无论是由主进程生成还是子进程来生成,其过程如下:

生成临时rdb文件,并写入数据。

完成数据写入,用临时文件替代正式rdb文件。

删除原来的db文件。

COW写时复制(copy-on-write)

fork创建出的子进程,与父进程共享内存空间。也就是说,如果子进程不对内存空间进行写入操作的话(Redis的子进程只做数据落盘的操作,也不会去写数据),内存空间中的数据并不会复制给子进程,这样创建子进程的速度就很快了!(不用复制,直接引用父进程的物理空间,玩的是指针)。

8117610e-126e-11ee-962d-dac502259ad0.png

当Redis父进程修改数据时,父进程会将原先的数据复制一份生成新的副本,然后修改父进程的指针,指向新的数据,此时父进程修改的新的数据不会影响到子进程。此时子进程的指针仍然指向旧的数据,子进程看到的数据还是bgsave时候的数据。当下一次执行bgsave时,新fork出来的子进程指针才会指向这次新的数据。

8132bd14-126e-11ee-962d-dac502259ad0.png

AOF(append-only file)

与RDB存储某个时刻的快照不同,AOF持久化方式会记录客户端对服务器的每一次写操作命令,并将这些写操作以追加的方式保存到以后缀为aof文件中,在Redis服务器重启时,会加载并运行aof文件的命令,以达到恢复数据的目的。

开启AOF持久化的方式

方式一:bgrewriteaof命令

>bgrewriteaof

方式二:通过配置文件自动触发

Redis默认不开启AOF持久化方式,我们可以在配置文件中开启并进行更加详细的配置:

#开启aof
appendonlyyes

#文件名称
appendfilename"appendonly.aof"

#同步方式
#appendfsync always #每次有新命令追加到 AOF 文件时就执行一次 fsync ,非常慢,也非常安全。
appendfsynceverysec#默认方式,每秒 fsync 一次,足够快,并且在故障时只会丢失 1 秒钟的数据。
#appendfsync no #从不 fsync ,将数据交给操作系统来处理。更快,也更不安全的选择。

重写

AOF将客户端的每一个写操作都追加到aof文件末尾,比如对一个key多次执行incr命令,这时候,aof保存每一次命令到aof文件中,aof文件会变得非常大。

127.0.0.1:6379>INCRreadcount
(integer)1
127.0.0.1:6379>INCRreadcount
(integer)2
127.0.0.1:6379>INCRreadcount
(integer)3
127.0.0.1:6379>INCRreadcount
(integer)4
127.0.0.1:6379>INCRreadcount
(integer)5

这是一种resp协议格式数据,星号后面的数字代表命令有多少个参数,$号后面的数字代表这个参数有几个字符

[root@redis6379]#catappendonly.aof
*2
$6
SELECT
$1
0
*2
$4
INCR
$9
readcount
*2
$4
INCR
$9
readcount
*2
$4
INCR
$9
readcount
*2
$4
INCR
$9
readcount
*2
$4
INCR
$9
readcount

手动执行重写命令BGREWRITEAOF:

127.0.0.1:6379>BGREWRITEAOF
Backgroundappendonlyfilerewritingstarted

重写后AOF文件里如下,将多个incr命令进行了合并

[root@redis6379]#catappendonly.aof
*2
$6
SELECT
$1
0
*3
$3
SET
$9
readcount
$1
5

重写配置参数

AOF重写redis会fork出一个子进程去做(与bgsave命令类似),不会对redis正常命令处理有太多影响:

auto‐aof‐rewrite‐min‐size64mb#aof文件至少要达到64M才会自动重写,文件太小恢复速度本来就很快,重写的意义不大
auto‐aof‐rewrite‐percentage100#aof文件自上一次重写后文件大小增长了100%则再次触发重写,例如上一次重写的大小是64M,那么下一次达到128M再做重写

AOF重写流程图

8158437c-126e-11ee-962d-dac502259ad0.png

在重写期间,由于主进程依然在响应命令,为了保证最终备份的完整性;因此它依然会写入旧的AOF file中,如果重写失败,能够保证数据不丢失。

为了把重写期间响应的写入信息也写入到新的文件中,因此也会为子进程保留一个buf,防止新写的file丢失数据。

重写是直接把当前内存的数据生成对应命令,并不需要读取老的AOF文件进行分析、命令合并。

不管是RDB还是AOF都是先写入一个临时文件,然后通过 rename 完成文件的替换工作。

混合持久化

重启 Redis 时,我们很少使用 RDB来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 RDB来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。通过如下配置可以开启混合持久化(前提必须先开启aof):

aof‐use‐rdb‐preambleyes#开启混合持久化

如果开启了混合持久化,AOF在重写时,不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将重写这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换。于是在 Redis 重启的时候,可以先加载 RDB 的内容,然后再重放增量 AOF 日志就可以完全替代之前的 AOF 全量文件重放,因此重启效率大幅得到提升。

127.0.0.1:6379>setk1
OK
127.0.0.1:6379>setk2
OK
127.0.0.1:6379>BGREWRITEAOF
Backgroundappendonlyfilerewritingstarted

查看此时的appendonly.aof文件:此时存放的是RDB的内容

[root@redis6379]#catappendonly.aof
REDIS0009�redis-ver5.0.7�
�edis-bits�@�ctime�%y�_used-mem��
aof-preamble���k�readcount��R��i9$�[root@redis6379]#

如果新增加了数据:

127.0.0.1:6379>setk3
OK

那么新的数据会以为RESP命令的方式追加在后面:

[root@redis6379]#catappendonly.aof
REDIS0009�redis-ver5.0.7�
�edis-bits�@�ctime�%y�_used-mem��
aof-preamble���k�readcount��R��i9$�*2
$6
SELECT
$1
0
*3
$3
set
$1
k
$1
3

混合持久化AOF文件结构如下:

817e9216-126e-11ee-962d-dac502259ad0.png

从持久化中恢复数据

数据的备份、持久化做完了,我们如何从这些持久化文件中恢复数据呢?如果一台服务器上有既有RDB文件,又有AOF文件,该加载谁呢?

其实想要从这些文件中恢复数据,只需要重新启动Redis即可。我们还是通过图来了解这个流程:

819d0188-126e-11ee-962d-dac502259ad0.png

启动时会先检查AOF文件是否存在,如果不存在就尝试加载RDB。那么为什么会优先加载AOF呢?因为AOF保存的数据更完整,通过上面的分析我们知道AOF基本上最多损失1s的数据。

RBD和AOF对比

81c7ec54-126e-11ee-962d-dac502259ad0.png

另外RBD不支持拉链,只有一个dump.rdb文件。

责任编辑:彭菁

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 硬盘
    +关注

    关注

    3

    文章

    1290

    浏览量

    57230
  • 服务器
    +关注

    关注

    12

    文章

    9016

    浏览量

    85171
  • 文件
    +关注

    关注

    1

    文章

    561

    浏览量

    24693

原文标题:如何快速实现 Redis 持久化

文章出处:【微信号:magedu-Linux,微信公众号:马哥Linux运维】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    EJB3持久规范

    EJB3持久规范1 实体
    发表于 07-07 15:37

    Redis坚持持久方式概述

    Redis 持久
    发表于 09-25 17:04

    Spark RDD的两个持久方法

    Spark_RDD的持久
    发表于 10-28 12:08

    Docker持久数据存储方案

    Docker持久存储与数据共享
    发表于 03-23 11:17

    OpenHarmony持久存储UI状态:PersistentStorage

    需要用到PersistentStorage。 PersistentStorage是应用程序中的可选单例对象。此对象的作用是持久存储选定的AppStorage属性,以确保这些属性在应用程序重新启动时的值与应用程序关闭时的值相同。 概述
    发表于 10-19 14:34

    Redis持久化分为两种:RDB和AOF

    Redis持久,一个老掉牙的问题,但是面试官就是喜欢问。这也是我们学Redis必会的一个知识点。
    的头像 发表于 02-21 09:22 666次阅读

    Redis持久机制介绍

    Redis持久机制? 为了能够重用Redis数据,或者防止系统故障,我们需要将Redis中的数据写入到磁盘空间中,即持久。Redis提供了两种不同的
    的头像 发表于 10-09 11:44 463次阅读
    Redis<b class='flag-5'>持久</b><b class='flag-5'>化</b>机制介绍

    Redis持久RDB方式介绍

    Redis持久 Redis是一个内存数据库,为了保证数据的持久性,它提供了两种持久方案: RDB
    的头像 发表于 10-09 14:56 483次阅读
    Redis<b class='flag-5'>持久</b><b class='flag-5'>化</b><b class='flag-5'>RDB</b><b class='flag-5'>方式</b>介绍

    redis持久方式有几种及配置

    Redis是一种内存数据库,为了避免数据丢失,需要将数据持久到磁盘上。Redis提供了两种持久方式
    的头像 发表于 12-04 11:09 605次阅读

    redis两种持久方式的区别

    的完整性和一致性。 Redis提供了两种持久方式RDB(Redis Database)和AOF(Append Only File)。这两种方式
    的头像 发表于 12-04 11:12 496次阅读

    redis的持久方式RDB和AOF的区别

    Redis 是一个高性能的键值对数据库,提供了两种持久方式RDB 和 AOF。RDB 是将 Redis 的数据快照保存到磁盘上,而 AO
    的头像 发表于 12-04 16:25 742次阅读

    redis持久机制和如何实现持久

    Redis是一款高性能的非关系型数据库,其持久机制是保证数据在重启后仍能够保存的关键。Redis提供了两种方式来实现持久
    的头像 发表于 12-05 10:02 440次阅读

    redis持久机制优缺点

    持久机制:RDB(Redis Database)和AOF(Append Only File)。 RDB持久
    的头像 发表于 12-05 10:03 668次阅读

    云容器redis持久配置

    丢失。 Redis提供了不同的持久机制,可以根据需要进行配置。本文将详细介绍云容器中Redis的持久配置及其相关配置项。 一、Redis的持久
    的头像 发表于 12-05 10:07 483次阅读

    redis持久rdb和aof一起用好处

    Redis是一个流行的内存数据库,它通过使用不同的持久机制来确保数据的持久性。RDB和AOF是Redis中两种常用的持久
    的头像 发表于 12-05 10:17 721次阅读