Redis的学习2之持久化RDB和AOF

一、Redis中的RDB持久化方式 (Snapshot快照)

1、RDB相关的概念:

RDB的简单理解:

  • RDB 是 Redis Database的缩写,在指定的时间间隔内将当前内存中的数据集快照写入磁盘。

详细的解释:

  1. Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。

  2. 整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失。

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

2、redis.conf的Snapshotting(快照)的相关设置

2.1默认的配置:
  • save 900 1 :在15分钟之内,有key被改变了1次,会进行保存
  • save 300 10:在5分钟之内,有key被改变了10次,会进行保存
  • save 60 10000: 一分钟之内,有key被改变了10000次(1万),会进行保存

在配置文件中#save "" 代表是被注释的,如果存在save "",则代表关闭,还有也可以使用动态所有停止RDB保存规则的方法的方法:redis-cli config set save ""

  • redis-cli:这是这是进入redis客户端的命令
  • config set save"" :这是设置RDB保存策略的命令,save “” 代表关闭

默认的文件名是:dbfilename dump.rdb,该文件是一个非常紧凑的文件

默认的保存位置是工作目录:dir ./

################################ SNAPSHOTTING  ################################
#
# Save the DB on disk:
#
#   save <seconds> <changes>
#
#   Will save the DB if both the given number of seconds and the given
#   number of write operations against the DB occurred.
#
#   In the example below the behaviour will be to save:
#   after 900 sec (15 min) if at least 1 key changed
#   after 300 sec (5 min) if at least 10 keys changed
#   after 60 sec if at least 10000 keys changed
#
#   Note: you can disable saving completely by commenting out all "save" lines.
#
#   It is also possible to remove all the previously configured save
#   points by adding a save directive with a single empty string argument
#   like in the following example:
#
#   save ""

save 900 1
save 300 10
save 60 10000

# By default Redis will stop accepting writes if RDB snapshots are enabled
# (at least one save point) and the latest background save failed.
stop-writes-on-bgsave-error yes

# Compress string objects using LZF when dump .rdb databases?
# For default that's set to 'yes' as it's almost always a win.
# If you want to save some CPU in the saving child set it to 'no' but
# the dataset will likely be bigger if you have compressible values or keys.
rdbcompression yes

# Since version 5 of RDB a CRC64 checksum is placed at the end of the file.

rdbchecksum yes

# The filename where to dump the DB
dbfilename dump.rdb

# The working directory.
dir ./

3、Redis中触发RDB的方式

3.1 ⾃动化触发RDB持久化的⽅式如下:
  • 根据 redis.conf 配置⾥的 SAVE m n 定时触发(实际上使⽤的是 BGSAVE)。
  • 主从复制时,主节点⾃动触发。
  • 执⾏ Debug Reload。
  • 执⾏ Shutdown 且没有开启 AOF 持久化
3.2 手动触发的方式:sava 或者是bgsave

3.2.1 命令的解释:

  • save:阻塞 Redis 的服务器进程,直到 RDB ⽂件被创建完毕。SAVE 命令很少被使⽤,因为其会阻塞主线程来保证快照的写⼊,由于 Redis 是使⽤⼀个主线程来接收所有客⼾端请求,这样会阻塞所有客⼾端请求。
  • bgsave:该指令会 Fork 出⼀个⼦进程来创建 RDB ⽂件,不阻塞服务器进程,⼦进程接收请求并创建 RDB 快照,⽗进程继续接收客⼾端的请求。

备注:可以通过使⽤ lastsave 指令来查看 BGSAVE 是否执⾏成功,lastsave 可以返回最后⼀次执⾏成功BGSAVE 的时间。

3.2.2 bgsave 的原理及流程:

启动流程:

  • 检查是否存在⼦进程正在执⾏ AOF 或者 RDB 的持久化任务。如果有则返回 false。
  • 调⽤ Redis 源码中的 rdbSaveBackground ⽅法,⽅法中执⾏ fork() 产⽣⼦进程执⾏ RDB 操作。
  • 了解关于fork() 中的 Copy-On-Write。

fork() 在 Linux 中创建⼦进程采⽤ Copy-On-Write(写时拷⻉技术),即如果有多个调⽤者同时要求相同资源(如内存或磁盘上的数据存储)。

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

3.3 执行 flushall 命令时触发

执行 flushall 命令清空数据库的时候也会触发,即生成一个内容为空的dump.rdb文件
注意:不要随意执行flushall命令,尤其是在公司使用的redis中

在使用RDB作为持久方式的时候,Redis是如何恢复数据的
先看一个命令:CONFIG GET dir获取dump.rdb文件的保存目录目录
Redis启动的时候会去读取dir中配置目录下的dump.rdb,将其中的数据重新载入到内存中。

4、RDB持久方式的优缺点:

4.1 优点:

  • 适合大规模的数据恢复
  • 对数据完整性和一致性要求不高

4.2缺点:

  • 数据丢失的风险较大

在一定间隔时间做一次备份,可能会因为 Redis 宕机⽽丢失从当前⾄最近⼀次快照期间的数据。

  • Fork的时候,内存消耗大

内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑,也可能会导致Redis在(毫秒级别的)短时间内无法响应客户端的请求。

  • 内存数据全量同步,数据量⼤的状况下,会由于 I/O ⽽严重影响性能

二、AOF的持久化方式:

1 、AOF相关概念的解析

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

总结:

  • AOF 记录除了查询以外的所有变更数据库状态的指令
  • 增量的形式追加保存到 AOF ⽂件中。

保存的文件
AOF保存的是appendonly.aof文件

2、Redis中AOF的相关配置:

  • appendonly yes:开启AOF持久化方式

在redis中默认是no不开启AOF的,需要设置yes进行开启

  • appendfilename "appendonly.aof":AOF持久方式中生成文件的默认名字是appendonly.aof
  • appendfsync everysec:默认保存策略everysec

保存策略
appendfsync always: (每修改同步)同步持久化 每次发生数据变更会被立即记录到磁盘 性能较差但数据完整性比较好。
appendfsync everysec:(每秒同步)异步操作,每秒记录 如果一秒内宕机,有数据丢失 。
appendfsync no:从不同步 。

  • auto-aof-rewrite-percentage 100:⽇志重写解决 AOF ⽂件不断增⼤的问题

随着写操作的不断增加,AOF ⽂件会越来越⼤。假设递增⼀个计数器 100 次,如果使⽤ RDB 持久化⽅式,我们只要保存最终结果 100 即可。⽽ AOF 持久化⽅式需要记录下这 100 次递增操作的指令,⽽事实上要恢复这条记录,只需要执⾏⼀条命令就⾏,所以那⼀百条命令实际可以精简为⼀条

############################## APPEND ONLY MODE ###############################

# By default Redis asynchronously dumps the dataset on disk. This mode is
# good enough in many applications, but an issue with the Redis process or
# a power outage may result into a few minutes of writes lost (depending on
# the configured save points).


appendonly yes

# The name of the append only file (default: "appendonly.aof")

appendfilename "appendonly.aof"

# The fsync() call tells the Operating System to actually write data on disk
# instead of waiting for more data in the output buffer. Some OS will really flush
# data on disk, some other OS will just try to do it ASAP.
#
# Redis supports three different modes:
#
# no: don't fsync, just let the OS flush the data when it wants. Faster.
# always: fsync after every write to the append only log. Slow, Safest.
# everysec: fsync only one time every second. Compromise.
#
# The default is "everysec", as that's usually the right compromise between
# speed and data safety. It's up to you to understand if you can relax this to
# "no" that will let the operating system flush the output buffer when
# it wants, for better performances (but if you can live with the idea of
# some data loss consider the default persistence mode that's snapshotting),
# or on the contrary, use "always" that's very slow but a bit safer than
# everysec.
#
# More details please check the following article:
# http://antirez.com/post/redis-persistence-demystified.html
#
# If unsure, use "everysec".

# appendfsync always
appendfsync everysec
# appendfsync no


# Automatic rewrite of the append only file.
# Redis is able to automatically rewrite the log file implicitly calling
# BGREWRITEAOF when the AOF log size grows by the specified percentage.
#
# This is how it works: Redis remembers the size of the AOF file after the
# latest rewrite (if no rewrite has happened since the restart, the size of
# the AOF at startup is used).

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

3、AOF启动的恢复数据的时候(在开启了AOF的条件下)

  • 正常情况:Redis重启的时候会去读取appendonly.aof,然后将执行appendonly.aof中的写操作,将数据重写到内存中。

  • 异常情况: 如果appendonly.aof出现损坏的时候,可以使用 redis-check-aof -fix 进行修复,再重启redis进行重新加载。

4、AOF持久化方式的优缺点:

4.1 优点:

  • 可读性高,适合保存增量数据,数据不易丢失

AOF依次保存了对数据库所有的写操作(是以Redis协议的格式保存),其内容容易让人读懂和理解,便于分析。

4.2缺点:
-⽂件体积⼤,恢复时间⻓

三、RDB-AOF 混合持久化⽅式

1、RDB-AOF 混合持久化⽅式的相关理解

Redis 4.0 之后推出了此种持久化⽅式,RDB 作为全量备份,AOF 作为增量备份,并且将此种⽅式作为默认⽅式使⽤。

在上述两种⽅式中,RDB ⽅式是将全量数据写⼊ RDB ⽂件,这样写⼊的特点是⽂件⼩,恢复快,但⽆法保存最近⼀次快照之后的数据,AOF 则将 Redis 指令存⼊⽂件中,这样⼜会造成⽂件体积⼤,恢复时间⻓等弱点。

在 RDB-AOF ⽅式下,持久化策略⾸先将缓存中数据以 RDB ⽅式全量写⼊⽂件,再将写⼊后新增的数据以 AOF 的⽅式追加在 RDB 数据的后⾯,在下⼀次做 RDB 持久化的时候将 AOF 的数据重新以 RDB 的形式写⼊⽂件。

这种⽅式既可以提⾼读写和恢复效率,也可以减少⽂件⼤⼩,同时可以保证数据的完整性。
在此种策略的持久化过程中,⼦进程会通过管道从⽗进程读取增量数据,在以 RDB 格式保存全量数据时,也会通过管道读取数据,同时不会造成管道阻塞。

可以说,在此种⽅式下的持久化⽂件,前半段是 RDB 格式的全量数据,后半段是 AOF 格式的增量数据。此种⽅式是⽬前较为推荐的⼀种持久化⽅式。

2、RDB-AOF持久化⽅式下数据的恢复:

启动Redis:

Redis 启动时会先检查 AOF 是否存在,如果 AOF 存在则直接加载 AOF,如果不存在 AOF,则直接加载 RDB ⽂件。

流程图:
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Hicodden/article/details/106943173