Redis持久化

redis中文网:
https://www.redis.net.cn/tutorial/3501.html

持久化的官网:可以翻译成中文
https://redis.io/docs/manual/persistence/

两种持久化方式简介:

Redis支持两种方式的持久化,一种是RDB方式、另一种是AOF(append-only-file)方式,两种持久化方式可以单独使用其中一种,也可以将这两种方式结合使用,AOF可以与RDB共存时,恢复时先加载AOF 。

•RDB:在指定的时间间隔内 将内存中的数据集快照写入磁盘,恢复时是将快照文件直接读取到内存里;会以一段时间内有指定次数据修改的规则触发 快照动作,快照文件名为dump.rdb,该文件默认使用LZF压缩算法 。每当Redis服务重启的时候会从该文件中加载数据进内存。

•AOF:采用日志的形式来记录每个写操作,并实时将 写命令 追加到aof文件末尾 ;AOF可以与RDB共存。但是恢复时先加载AOF 。

RDB持久化模式(单独使用):

RDB的持久化方式是 在指定的时间间隔内将内存中的数据以快照的形式保存到磁盘,它是Redis默认的持久化方式

RDB持久化方式有两种:1.可以根据配置中的策略自动触发,2.也可以根据redis命令手动触发;

1.根据redis.conf配置文件中的策略自动触发持久化:

redis.conf配置文件修改以下几个内容:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

1.根据配置自动触发RDB持久化:

Redis内部可以自动触发RDB持久化。自动触发的RDB持久化都是采用bgsave的方式,减少Redis进程的阻塞

Redis允许用户自定义快照条件,当符合快照条件时,Redis会自动执行快照操作。快照的条件可以由用户在配置文件中配置。配置文件中配置格式如下:

save n m

例如:

#RDB持久化策略 默认三种方式,[900秒内有1次修改],
#[300秒内有10次修改],[60秒内有10000次修改]即触发RDB持久化,
#我们可以手动修改该参数或新增策略
save 900 1
save 300 10
save 60 10000
 
#RDB文件名
dbfilename dump.rdb
#RDB文件存储路径
dir /opt/app/redis6/data
策略配置:
#在seconds秒内有changes次数据修改就触发RDB持久化

第一个参数是时间窗口,第二个是键的个数,也就是说,在第一个时间参数配置的,时间范围内被更改的键的个数大于后面配置的changes时,即符合快照条件。当触发条件时,Redis会自动将内存中的数据生成一份副本rbd文件并存储在磁盘上,进行一个数据持久化,这个过程称为快照。

在配置好 配置文件以后,先使用kill -9 redis服务进程号停止服务,然后重启Redis,进行测试:
配置的是save 5 2:即5秒内有两个数据的更改就持久化数据到磁盘文件:

在这里插入图片描述

2.根据redis命令手动触发RDB持久化:

以下几种情况会触发持久化:

  1. 用户执行save或者bgsave命令
  2. 当从节点做全量复制时,主节点会自动执行bgsave操作,并且把生成的RDB文件发送给从节点。
  3. 执行debug reload命令时,也会自动触发bgsave操作。
  4. 执行shutdown命令时,如果没有开启AOF持久化也会自动触发bgsave操作。
  5. 执行FLUSHALL命令

save和bgsave命令:

除了让Redis自动进行快照以外,当我们对服务进行重启或者服务器迁移我们需要人工去干预备份。redis提供了两条命令来完成这个任务

1、save命令:

1.1 save命令介绍:

save会阻塞服务器进程,在进行save的过程中,服务器不能处理任何请求;

当执行save命令时,Redis同步做快照操作,在快照执行过程中会阻塞所有来自客户端的请求。当redis内存中的数据较多时,通过该命令将导致Redis较长时间的不响应。所以不建议在生产环境上使用这个命令,而是推荐使用bgsave命令:

1.2 save命令的流程:

在这里插入图片描述

1.3 save命令的使用:

在这里插入图片描述

在这里插入图片描述

2、bgsave命令,即backgound save:

2.1 bgsave介绍:

而bgsave会通过一个子进程在后台处理rdb持久化。事实上save和bgsave调用的都是rdbSave函数,因此Redis不允许save和bgsave同时运行,这也是为了避免出现竞争导致rdb文件数据不准确

bgsave操作使用CopyOnWrite机制进行写时复制,是由一个子进程将内存中的最新数据遍历写入临时文件,此时父进程仍旧处理客户端的操作,当子进程操作完毕后再将该临时文件重命名为dump.rdb替换掉原来的dump.rdb文件,因此无论bgsave是否成功,dump.rdb都不会受到影响

另外在主从全量同步、debug reload以及shutdown的情况下也会触发RDB数据持久化

2.2. bgsave命令的具体流程:

bgsave命令的具体流程如下图:

在这里插入图片描述

bgsave命令的具体流程如下:

  1. 执行bgsave命令,Redis进程先判断当前是否存在正在执行的RDB或AOF子线程,如果存在就是直接结束。
  2. Redis进程执行fork操作创建子线程,在fork操作的过程中Redis进程会被阻塞。
  3. Redis进程fork完成后,bgsave命令就结束了,自此Redis进程不会被阻塞,可以响应其他命令。
  4. 子进程根据Redis进程的内存生成快照文件,并替换原有的RDB文件。
  5. 子进程通过信号量通知Redis进程已完成。

bgsave命令,bgsave命令可以在后台异步地进行快照操作,快照的同时服务器还可以继续响应来自客户端的请求。执行BGSAVE后,Redis会立即返回ok表示开始执行快照操作,

bgsave是异步执行快照的,在调用fork函数创建子进程时,只对这个时间之前的数据集进行备份(fork函数创建的子进程,是复制该时间点的父进程的,该时间点之后的数据是没有复制的),该时间点之后客户端对redis服务端发送的命令对数据的修改,是没有持久化的没有保存到快照中:

在这里插入图片描述

2.3 bgsave使用:

在这里插入图片描述

在这里插入图片描述

3.flushdb和flushall 的区别:

在redis中,flushdb和flushall 都是清空当前数据库的操作,但是两者有很大的区别:

1、flushall 清空数据库并执行持久化操作,也就是rdb文件会发生改变,变成76个字节大小(初始状态下为76字节),所以执行flushall之后数据库真正意义上清空了.

2、flushdb 清空数据库,但是不执行持久化操作,也就是说rdb文件不发生改变。而redis的数据是从rdb快照文件中读取加载到内存的。所以在flushdb之后,如果想恢复数据库,则可以直接kill掉redis-server进程,然后重新启动服务,这样redis重新读取rdb文件,数据恢复到flushdb操作之前的状态。

注意:要直接kill 掉redis-server服务,因为shutdown操作会触发持久化.

lsof -i:6379 命令查看redis-server的进程号,然后kill即可

4.RDB持久化的优缺点:

一、优势:

1.RDB是一个非常紧凑(compact)的文件,它保存了redis 在某个时间点上的数据集,这种文件非常适合用于进行备份和灾难恢复。

2.生成RDB文件的时候,redis主进程会fork()出一个子进程来处理所有保存工作,主进程不需要进行任何磁盘IO操作。

3.RDB 在恢复大数据集时的速度比AOF的恢复速度要快。

二、劣势:

•1、RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行fork操作创建子进程,频繁执行成本过高

•2、在一定间隔时间做一次备份,所以如果redis意外down掉的话,最后一次快照之后的修改数据会被丢失(数据有丢失)。

如果数据相对来说比较重要,希望将损失降到最小,则可以使用AOF方式进行持久化。

5.RDB备份恢复:

在这里插入图片描述

AOF持久化方式(单独使用):

1.AOF持久化介绍:

AOF 的运作方式是 以日志的形式 不断地将写命令 追加appendonly.aof到文件的末尾.

在这里插入图片描述

AOF(Append Only File):Redis 默认不开启AOF,开启了AOF之后,RDB就默认不使用了。AOF采用日志的形式来记录每个写操作,并追加到文件中。开启后,执行更改Redis数据的命令时,就会把命令写入到AOF文件中。

Redis 重启时会根据日志文件的内容把写指令从前到后执行一次以完成数据的恢复工作。

AOF(Append-Only File)记录Redis中每次的写命令,类似mysql中的binlog,服务重启时会重新执行AOF中的命令将数据恢复到内存中,RDB(按策略持久化)持久化方式记录的粒度不如AOF(记录每条写命令),因此很多生产环境都是开启AOF持久化。

2.配置文件中的AOF策略:

一般都是选择第一种[always:每个命令都记录],
[everysec:每秒记录一次],[no:看机器的心情高兴了就记录]

如何配置AOF:

#开启AOF持久化
appendonly yes
 
#AOF文件名
appendfilename "appendonly.aof"
 
#AOF文件存储路径 与RDB是同一个参数,共用一个文件路径
dir ./  #即bin目录下
 
#AOF策略,一般都是选择第一种[always:每个命令都记录],
#[everysec:每秒记录一次],[no:看机器的心情高兴了就记录,linux一般半个小时同步一次]
#appendfsync always
appendfsync everysec
# appendfsync no
 
 
#aof文件大小比起上次重写时的大小,增长100%(配置可以大于100%)时,触发重写。
#[假如上次重写后大小为10MB,当AOF文件达到20MB时也会再次触发重写,以此类推]
auto-aof-rewrite-percentage 100 
 
#aof文件大小超过64MB*2时,触发重写,
#为何要乘以2,因为auto-aof-rewrite-percentage 100 是翻倍即100%,达到翻倍时才重写
auto-aof-rewrite-min-size 64mb 

3.AOF持久化实践:

AOF持久化单独起作用,需要关闭混合模式,混合模式aof-use-rdb-preamble 高版本是默认打开的。

我们的redis.conf配置:
第一步:关闭save配置,即注释掉save x x,也就是关闭RDB模式
第二步:关闭混合模式,改成:aof-use-rdb-preamble no
第三步:打开aof模式,改成的appendonly yes
其他默认。appendfsync everysec

测试AOF持久化:

修改配置文件之后,一定要停止redis服务,并重新启动才能生效新配置:

ps -ef |grep redis #查找redis进程
kill -9 server的进程号
ps -ef |grep redis #再次查看是否停掉了redis服务
redis-server redis.conf #重新以配置文件形式启动redis服务
redis-cli #连接客户端

在这里插入图片描述

然后重新启动一个控制台,连接客户端,redis-cli
然后 设置set k1 v1 等进行测试:
然后查看appendonly.aof文件大小和内容:cat appendonly.aof
在这里插入图片描述

4.AOF数据恢复和数据修复:

在这里插入图片描述
aof的数据备份和恢复:
①先备份aof文件

cp appendonly.aof appendonly_bk.aof
rm -rf appendonly.aof
ll

在这里插入图片描述

②然后将备份文件找到并修改名字为appendonly.aof,并放到redis-server的同级目录,此文件会自动加载并恢复数据:

mv appendonly_bk.aof appendonly.aof

③杀掉redis服务进程,并重新启动服务–>重新连接客户端:

ps -ef |grep redis #查找redis进程
kill -9 server的进程号
ps -ef |grep redis #再次查看是否停掉了redis服务
redis-server redis.conf #重新以配置文件形式启动redis服务
重新开启一个控制台,重连客户端redis-cli ,并查看数据:

在这里插入图片描述
此时也可以查看aof中的数据:
在这里插入图片描述
AOF异常恢复:

故意修改aof文件,让其出错:
在这里插入图片描述
然后重新启动redis服务测试:发现连接被拒绝
在这里插入图片描述

异常修复命令:
redis-check-aof --fix appendonly.aof

在这里插入图片描述

在这里插入图片描述
然后重新启动redis服务,连接客户端并测试keys *

在这里插入图片描述

5.AOF持久化流程:

开启了AOF之后,RDB就默认不使用了。使用下面的配置开启AOF以及策略。(如果使用AOF,推荐选择always方式持久化,否则在高并发场景下,每秒钟会有几万甚至百万条请求,如果使用everysec的方式的话,万一服务器挂了那几万条数据就丢失了);

AOF持久化流程:

  1. 客户端的请求写命令会被append追加到AOF缓冲区内;
  2. AOF缓冲区根据AOF持久化策略[always,everysec,no]将操作sync同步到磁盘的AOF文件中;
  3. AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量;
  4. Redis服务重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的;
    在这里插入图片描述
  • 命令追加(append):所有写命令都会被追加到AOF缓存区(aof_buf)中。
  • 文件同步(sync):根据不同策略将AOF缓存区同步到AOF文件中。
  • 文件重写(rewrite):定期对AOF文件进行重写,以达到压缩的目的。
  • 数据加载(load):当需要恢复数据时,重新执行AOF文件中的命令。

6.AOF文件重写压缩

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

AOF持久化机制记录每个写命令,当服务重启的时候会复现AOF文件中的所有命令,会消耗太多的资源且重启很慢。因此为了避免AOF文件中的写命令太多文件太大,Redis引入了AOF的重写机制来压缩AOF文件体积AOF文件重写是把Redis进程内的数据转化为写命令同步到新AOF文件的过程

Bgrewriteaof 命令用于异步执行一个 AOF(AppendOnly File) 文件重写操作。重写会创建一个当前 AOF 文件的体积优化版本

即使 Bgrewriteaof 执行失败,也不会有任何数据丢失,因为旧的 AOF 文件在 Bgrewriteaof 成功之前不会被修改。

注意:从 Redis 2.4 开始, AOF 重写由 Redis 自行触发, BGREWRITEAOF 仅仅用于手动触发重写操作。

重写会根据重写策略或手动触发AOF重写。

AOF持久化流程中的文件重写可以手动触发,也可以自动触发:

  • 手动触发:使用bgrewriteaof命令。
  • 自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage配置确定自动触发的时机。auto-aof-rewrite-min-size表示运行AOF重写时文件大小的最小值,默认为64MB;auto-aof-rewrite-percentage表示当前AOF文件大小和上一次重写后AOF文件大小的比值的最小值,默认为100。只用前两者同时超过时才会自动触发文件重写。

重写流程:

  1. bgrewriteaof触发重写,判断是否当前有bgsave或bgrewriteaof在运行,如果有,则等待该命令结束后再继续执行。
  2. 主进程fork出子进程执行重写操作,保证主进程不会阻塞。
  3. 子进程遍历redis内存中数据到临时文件,客户端的写请求同时写入aof_buf缓冲区和aof_rewrite_buf重写缓冲区 保证原AOF文件完整以及新AOF文件生成期间的新的数据修改动作不会丢失。
  4. 1).子进程写完新的AOF文件后,向主进程发信号,父进程更新统计信息。2).主进程把aof_rewrite_buf中的数据写入到新的AOF文件。
  5. 使用新的AOF文件覆盖旧的AOF文件,完成AOF重写。

如下图:

在这里插入图片描述

AOF相关问题

问题1:数据都是实时持久化到磁盘吗?

虽然每次执行更改Redis数据库内容的操作时,AOF都会将命令记录在AOF文件中,但是事实上,由于操作系统的缓存机制,数据并没有真正地写入硬盘,而是进入了aof_buf缓存中。在默认情况下系统每30秒会执行一次同步操作。以便将aof_buf缓存中的内容真正地写入磁盘中。

在这30秒的过程中如果系统异常退出则会导致aof_buf缓存中的数据丢失。这个时候就需要Redis在写入AOF文件后主动要求系统将aof_buf缓存内容同步到磁盘中。在redis.conf中通过如下配置来设置同步机制。

fork()叉出一个子进程,通过子进程将aof_buf缓存中的数据同步到磁盘中:

在这里插入图片描述

在这里插入图片描述

问题2:文件越来越大,怎么办?

AOF持久化是Redis不断将写命令记录到 AOF 文件中,随着Redis不断的运行,AOF 的文件会越来越大,文件越大,

为了解决这个问题,Redis新增了重写机制,

当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。

AOF 文件重写并不是对原文件进行重新整理,而是直接读取服务器现有的键值对,然后用一条命令去代替之前记录这个键值对的多条命令,生成一个新的文件后去替换原来的 AOF 文件。

在启动时,Redis会逐个执行AOF文件中的命令来将硬盘中的数据载入到内存中,载入的速度相对于RDB会慢一些

AOF重写机制触发时机:

在这里插入图片描述

问题3:重写过程中,AOF文件被更改了怎么办?

Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写:重写后的新 AOF 文件包含了重写这一时刻之前数据集所需的最小命令集合。

在aof_buf缓存到旧的aof文件中间其实还有一个子进程,将aof_buf缓存中的数据同步到aof文件中取。

(3)重写子进程会将redis服务中的所有数据键值通过一条指令替代。

Redis允许同时开启AOF和RDB,既保证了数据安全又使得进行备份等操作十分容易。如果同时开启后,Redis重启会使用AOF文件来恢复数据,因为AOF方式的持久化可能不太会丢失数据。

AOF 持久化优缺点:

优点:
1.备份机制更稳健,丢失数据概率更低。
2.可读的日志文本,通过操作 AOF更稳健,可以处理误操作。

在这里插入图片描述

缺点:

在这里插入图片描述

1.对于具有相同数据的的Redis,AOF 文件通常会比 RDB 文件体积更大(RDB存的是数据快照)。
2.恢复备份速度慢。
3.每次读写都同步的话,有一定的性能压力,即性能不高。
4.存在个别bug,不能恢复数据。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

RDB 和 AOF 之间的相互作用:

在版本号大于等于 2.4 的 Redis 中, BGSAVE 执行的过程中, 不可以执行 BGREWRITEAOF 。 反过来说, 在 BGREWRITEAOF 执行的过程中, 也不可以执行 BGSAVE 。
这可以防止两个 Redis 后台进程同时对磁盘进行大量的 I/O 操作。
如果 BGSAVE 正在执行, 并且用户显示地调用 BGREWRITEAOF 命令, 那么服务器将向用户回复一个 OK 状态, 并告知用户, BGREWRITEAOF 已经被预定执行: 一旦 BGSAVE 执行完毕, BGREWRITEAOF 就会正式开始。当 Redis 启动时, 如果 RDB 持久化和 AOF 持久化都被打开了, 那么程序会优先使用 AOF 文件来恢复数据集, 因为 AOF 文件所保存的数据通常是最完整的

AOF+RDB混合[推荐]:

两种方式混合才是王道:即同时开启:
在这里插入图片描述

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

aof-use-rdb-preamble yes # redis5.0后默认开启

Redis4之后支持RDB-AOF混合持久化的方式,结合了两者的优点,可以通过 aof-use-rdb-preamble 配置项可以打开混合开关。

介绍
看了上面的RDB和AOF的介绍后,我们可以发现,使用RDB持久化会有数据丢失的风险,但是恢复速度快,而使用AOF持久化可以保证数据完整性,但恢复数据的时候会很慢。于是从Redis4之后新增了混合AOF和RDB的模式,先使用RDB进行快照存储,然后使用AOF持久化记录所有的写操作,当重写策略满足或手动触发重写的时候,将最新的数据存储为新的RDB记录。这样的话,重启服务的时候会从RDB和AOF两部分恢复数据,即保证了数据完整性,又提高了恢复的性能。

开启混合模式后,每当bgrewriteaof命令之后会在AOF文件中以RDB格式写入当前最新的数据,之后的新的写操作继续以AOF的追加形式追加写命令。当redis重启的时候,加载 aof 文件进行恢复数据:先加载 rdb 的部分再加载剩余的 aof部分。

在这里插入图片描述

配置
修改下面的参数即可开启AOF,RDB混合持久化:

vim /usr/local/bin/redis.conf

aof-use-rdb-preamble yes

使用
开启混合持久化模式后,重写之后的aof文件里和rdb一样存储二进制的 快照数据,继续往redis中进行写操作,后续操作在aof中仍然是以命令的方式追加。因此重写后aof文件由两部分组成,一部分是类似rdb的二进制快照,另一部分是追加的命令文本.

如果开启了混合持久化,触发机制是AOF在重写所以一定要开启AOF持久化。在AOF在重写时,不再是单纯aof文件中的命令进行重写,而是将重写这一刻之前的内存做一次整体的RDB dump处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一起,都写入新的AOF临时文件,等到重写完会对临时的AOF文件进行改名,覆盖原有的AOF文件,完成新旧两个AOF文件的替换。

混合模式实践:

第一步:开启save配置,即打开save x x,也就是关闭RDB模式
第二步:开启混合模式,改成:aof-use-rdb-preamble yes
第三步:打开aof模式,改成的appendonly yes
其他默认。appendfsync everysec

在这里插入图片描述

redis.conf配置文件的 aof配置修改后重新启动:
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

总结:

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值