6、Redis持久化
6.1、背景
首先Redis作为一种缓存性数据库,如果缓存中有数据,他可以很快的把数据返回给客户,至于为什么他可以很快的将数据返回给客户,主要是因为他是一种内存性数据库
,不需要额外的IO操作,减少了访问磁盘的所需要的时间,但是他家都知道,内存(RAM)是一种断电即失
的存储结构但是数据是一种很珍贵的资源,如果断电就失去,将会造成很大的事故,该如何将数据持久化到磁盘中,进过一段时间的探索,发现可以通过RDB或者AOF将数据写入到到磁盘中,即数据持久化
,这样就可以防止断电时数据丢失,如果害怕放在一个磁盘时,磁盘损坏丢失数据,此时就可以使用集群来解决。
6.2、数据持久化之RDB
6.2.1、简介
RDB(Redis DataBase)是Redis默认的一种数据持久化方式,它通过在指定的时间间隔以指定的次数将内存中数据集以快照
的方式写入一个二进制文件中,然后写入到硬盘中,也就是Snapshot快照,它恢复时将快照文件直接读到内存里。默认生成的文件为dump.rdb
RDB是Redis默认的一种持久化方式
RDB持久化数据时主要有两种策略,一种是手动触发,另外一种的自动触发
6.2.1.1 、手动触发(save)
save:在主线程中进行保存数据快照,由于Redis是单线程的,也就是说所有的客户端请求都是由它的主线程来进行处理的。save操作会阻塞所有客户端请求,执行save指令期间,redis服务器不能执行其他命令的操作,直至持久化完成**(不推荐使用)**。
6.2.1.2、自动触发
bgsava(background save):又叫做后台异步保存,当内存增长到指定值或者百分比时,会自动触发bgsave。此时Redis会调用fork函数,单独创建(fork )一个子进程进行持久化,子进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,它是一个全新的进程,此时父进程继续处理所有客户端请求,子进程将内存上的数据全部写到临时文件中,待持久化过程都结束后,再用这个临时文件替换
(是指全量替换,而不是增量替换,埋下伏笔[当数据较大时,会很浪费时间,因为会引起大量的磁盘IO操作])上次持久化好的文件(*.rdb)。整个过程中,主进程是不进行任何IO操作的,这就是确保了极高的性能。
如果redis没有开启AOF持久化,在redis进行shutdown关闭时,会自动执行bgsave(使用kill关闭redis,则不会执行bgsave)。
6.2.2、配置RDB持久化
- 可以在redis.conf中进行持久化的相关配置,主要设计的配置信息如下:
# 备份文件,即dump.rdb的位置
dir /opt/redis-6.2.12/master-slave/
# 备份文件的名称 默认为dump.rdb
dbfilename dump.rdb
#rdb文件是否压缩,默认为yes
rdbcompression yes
# 是否检查备份文件的完整性,默认为yes
rdbchecksum yes
#当redis磁盘满时,是否停止redis写操作,默认为yes
stop-writes-on-bgsave-error yes
#备份策略
# 格式 save 秒 写的次数
# save 3600 1
# save 300 100
# 每隔1分钟写1w次
save 60 10000
恢复时只需要将本分文件放入到工作目录下,然后启动redis服务即可。
2.写入数据
#批量写入数据
# 由于我采用的是集群,在批量写入时,需要指定组,否则无法批量写入
mset k1{g1} v2 k2{g1} v2 k3{g1} v3 k4{g1} v3
# 查看是否写入数据
mget k1{g1} k2{g1} k3{g1} k4{g1}
3.备份rdb文件,用于恢复时使用
#从上面可以看出,需要备份的rdb文件(用于恢复)是6385
cp dump_6385.rdb dump_6385bak.rdb
4.清空数据库
flushall
可以查看此时数据库中已经没有数据了
5.恢复
只需要将备份的rdb文件替换为之前的rdb文件,然后重启服务即可.
由于rdb在持久化后,采用的是全量替换,而不是增量替换,故需要大量的对磁盘进行IO操作,很浪费时间。
6.禁用RDB
save ""
6.3、数据持久化之AOF
6.3.1、简介
AOF(Append-Only File):顾名思义就是在文件中追加内容,即将redis中所有的写指令记录下来 (以日志的形式记录每个写操作
),然后追加到对应的文件中,不允许修改文件中原有内容,只允许追加新的内容。
当Redis在使用AOF持久化机制的情况下宕机后重新启动,Redis会通过加载AOF文件来重新构建数据库的状态。这个过程不涉及全量复制或增量复制的概念。
在Redis启动时,它会读取AOF文件中记录的所有命令并按顺序
重新执行。这意味着Redis会逐个重放AOF文件中的写命令,以还原数据到宕机前的状态。
因此,即使Redis在宕机前有过多次写操作,Redis启动后也会通过读取AOF文件中的命令来逐个恢复这些写操作,让数据库的状态与宕机前保持一致。
默认情况下AOF是关闭的,需要手动开始,即在redis.conf配置文件中将appendonly的值设置为yes
6.3.2、持久化流程
-
客户端发送命令,发送的命令不是直接写入到AOF文件中的,而是以某种协议的格式将被执行的写命令追加到服务器状态的
aof_buf 缓冲区
的末尾。即将写命令写入AOF缓冲区中. -
在AOF缓冲区的写命令根据配置的策略判断如何写入到AOF文件中。
配置项 写回机制 优点 缺点 always 同步写回,即每个写命令执行完立刻同步地将日志写回磁盘 数据完整性好,可靠性高 影响性能,因为每个写操作都要写入磁盘中 Everysec(默认) 每秒写回,即每个写命令执行完先把日志写到AOF缓冲区, 再每隔一秒把缓冲区内容写入磁盘 性能一般 数据完整性不能得到保证,即服务器宕机是丢失1s数据 no 操作系统控制写回(完全异步),即每个写命令执行完先把日志写到AOF缓冲区,再由操作系统决定何时将缓冲区内容写回磁盘 性能较好 数据完整性不能得到保证,即服务器宕机是丢失数据较多 -
当AOF文件的大小超过指定的大小时,将会对AOF重新(rewrite),压缩AOF文件的大小。
-
当Redis重启服务时,会重新加载AOF文件中的写操作,
并按顺序
重新执行。这意味着Redis会逐个重放AOF文件中的写命令,以还原数据到宕机前的状态
6.3.3 配置AOF持久化
1.可以在redis.conf中进行持久化的相关配置,主要设计的配置信息如下:
#配置AOF持久化,默认为 no,即不开启
appendonly yes
# 备份文件的位置
dir /opt/redis-6.2.12/master-slave/
#备份文件的名称,默认为appendonly.aof"
appendfilename "appendonly.aof"
#写入AOF文件时的策略,默认为每隔1s将AOF缓冲区的写操作同步至AOF文件中
# appendfsync always
appendfsync everysec
# appendfsync no
#重写开启条件,默认自动重写大小为64MB 上一次重写占比100%,
#当AOF文件的大小超过上一次重写后大小的一定百分比时(默认为100),或者超过64MB
#Redis会自动启动AOF重写过程,以减小AOF文件的体积。
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
#Redis启动时,如果AOF文件被截断(部分数据被裁剪)的操作,默认为yes
# yes:忽略截断的部分,并警告用户。
# no:忽略截断并继续启动,不警告用户
aof-load-truncated yes
#是否添加RDB文件的内容,默认为yes,即在AOF文件中首先添加RDB文件的内容,以节省加载AOF文件时的时间。
#no 不添加RDB文件内容到AOF文件中。
aof-use-rdb-preamble yes
#在执行AOF重写期间是否禁止对AOF文件进行fsync。当Redis执行AOF重写时,它会生成一个新的AOF文件来替换现有的AOF文件,默认为 no
#即在AOF重写期间不禁用AOF文件的fsync操作。当Redis执行AOF重写时,它会在每个写入操作后同步AOF文件到硬盘,以提供持久化保证。
#如果设置为yes,则在AOF重写期间,Redis将禁止对AOF文件执行fsync操作。这意味着在重写期间,Redis不会将重写操作同步到硬盘。
no-appendfsync-on-rewrite no
2.恢复
AOF的备份机制和性能虽然和RDB不同,但是备份和恢复的操作同RDB一样,都是拷贝备份文件,需要恢复时再拷贝到Redis工作目录下,启动系统即加载。
AOF的恢复方式主要分为两种,即正常恢复和异常恢复
-
正常恢复
修改默认的appendonly no,改为yes将有数据的aof 文件复制一份保存到对应的目录(查看目录:config get dir )恢复:重启redis 然后重新加载
-
异常恢复修
改默认的appendonly no,改为yes如遇到aof 文件损坏,通过 /usr/local/bin/redis-check-aof - -fix appendonly.aof 进行恢复
6.4、RDB与AOF的优缺点
6.5、选取方案
综上所述Redis在进行数据持久化时,主要有两种方式,那么我们该如何选择呢?
- 当数据不敏感时,可以只选择默认持久化方式,即RDB
- 当对数据的恢复速度要求较快时,建议两种方式都是用
- 如果只做缓存,则两种方式都可以不使用
- 由于AOF本身存在缺陷,所以在使用AOF进行持久化时,一定也要使用RDB方式
- 如果应用程序对数据的完整性和可靠性要求非常高,可以选择使用AOF持久化。AOF记录每个写入操作,这样可以更好地保护数据免受故障和断电的影响。另一方面,如果对数据的一致性要求较低或可以容忍一些数据丢失,则可以考虑使用RDB持久化机制。
- 写入频率和性能:如果应用程序有很高的写入频率,那么AOF持久化可能会对写入性能产生一些影响,因为每个写操作都要追加到AOF文件中。相比之下,RDB持久化对写入性能的影响较小,因为它将数据库的快照保存到磁盘。所以,如果写入性能对应用程序至关重要,可以考虑使用RDB持久化。
- 恢复速度和复杂度:从故障中恢复时,AOF持久化需要逐个重放AOF文件中的写操作,这会增加恢复的时间。相比之下,RDB持久化只需要加载上次保存的快照,恢复速度更快。另外,AOF持久化需要更多的磁盘空间来存储AOF文件,而RDB持久化需要较少的空间。因此,在考虑恢复速度和存储需求时需要权衡。
- 备份和恢复需求:如果需要进行频繁的备份和恢复操作,AOF持久化可能更适合。AOF文件以文本形式保存命令历史,可以轻松进行备份、恢复和数据修复。相比之下,RDB文件是二进制格式,不太适合直接操作和恢复。
至于到底选择那种持久化方式,需要根据自己业务,权衡两种方式的利弊
redis集群:化神之境