redis持久化
基本概念
由于Redis是一个内存数据库,所有数据都是存在内存中,容易丢失,因此需要进行定期的持久化来防止数据丢失,确保数据的安全性。
所谓持久化,简单来讲,就是将数据以某种形式持久化到磁盘上。
持久化方案
Redis支持两种持久化方案:
- RDB持久化方案
- AOF持久化方案
RDB和AOF可以同时开启
RDB持久化方案
在指定时间间隔后对内存中的数据做快照,将快照持久化到磁盘上。
持久化后生成一个压二进制文件XXX.rdb(默认压缩)
RDB持久化配置
dbfilename dump.rdb
#说明:设置本地数据库文件名,默认值为dump.rdb经验:通常设置为dump-端口号.rdb
dir
#说明:设置存储.rdb文件的路径
#经验:通常设置成存储空间较大的目录中,目录名称data.
rdbcompression yes
#说明:设置存储至本地数据库时是否压缩数据,默认为yes,采用LZF 压缩
#经验:通常默认为开启状态,如果设置为no,可以节省CPU 运行时间,但会使存储的文件变大(巨大)
rdbchecksum yes
#说明:设置是否进行RDB文件格式校验,该校验过程在写文件和读文件过程均进行
#经验:通常默认为开启状态,如果设置为no,可以节约读写性过程约10%时间消耗,但是存在一定的数据损坏风险
RDB触发条件
RDB触发可以分为自动触发和手动触发。
手动触发方式
- save:会阻塞当前Redis服务器,直到持久化完成,线上应该禁止使用。
- bgsave:该触发方式会fork一个子进程,由子进程负责持久化过程,因此阻塞只会发生在fork子进程的时候。
save会阻塞当前Redis服务器,直到RDB完成,一般不会使用。
bgsave工作流程如下:

注意
由于Redis使用fork来复制一份当前进程,那么子进程就会占有和主进程一样的内存资源,比如说主进程8G内存,那么在备份的时候,必须保证有16G的内存,要不然会启用虚拟内存,性能非常的差。
自动触发
RDB持久化可以指定时间间隔和数据量作为一个条件。
- 自动触发时间策略时间策略:
- 允许多个时间策略,是因为不同时间断的数据不均衡,可以根据具体情况灵活设置多个条件,来满足不同时间段的需求。
- 同一个条件的间隔和数量必须同时满足,多个条件之间满足一个就行。
- 手动触发方式
# 示例
#save [seconds] [changes]
#意为在[seconds]秒内如果发生了[changes]次数据修改,则进行一次RDB快照保存
save 900 1 # 900秒内至少有一个键值被更改
save 300 10 # 300秒内至少有一个键值被更改
save 60 10000 # 60秒内至少有10000个键值被更改
上述三个条件只要有一条满足就会触发RDB持久化。
自动触发场景
- 根据我们的 save [seconds] [changek
在这里插入代码片s] 配置规则自动触发; - 从节点全量复制时,主节点发送rdb文件给从节点完成复制操作,主节点会触发 bgsave;
- 执行 shutdown时,如果没有开启aof,也会触发。(即shutdown时AOF的优先级高于bgsave)
AOF持久化方案
以独立日志的方式记录每次写命令。AOF主要解决数据持久化的实时性问题。
AOF的整个流程大体来看可以分为两步
- 一步是命令的实时写入(如果是 appendfsync everysec 配置,会有1s损耗)
- 第二步是对aof文件的重写。
AOF写数据三种策略
- always(每次)
- 每次写入操作均同步到AOF文件中,数据零误差,性能较低,不建议使用
- everysec(每秒):在系统突然宕机的情况下丢失1秒内的数据
- 每秒将缓冲区中的指令同步到AOF文件中,数据准确性较高,性能较高,建议使用,也是默认配置
- no(系统控制)
- 由操作系统控制每次同步到AOF文件的周期,整体过程不可控
AOF重写
随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis引入了AOF重写机制压缩文件体积。AOF文件重写是将Redis进程内的数据转化为写命令同步到新AOF文件的过程。
简单来讲,就是将对同一个数据的若干条命令执行结果转化成最终结果数据对应的指令进行记录。
- AOF重写规则
1.进程内已超时的数据不再写入文件
2.忽略无效指令,重写时使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令
如del key1、hdelkey2、sremkey3、set key4 111、set key4 222等
3.对同一数据的多条写命令合并为一条命令
如lpushlist1 a、lpushlist1 b、lpushlist1 c 可以转化为:lpushlist1 a b c。
为防止数据量过大造成客户端缓冲区溢出,对list、set、hash、zset等类型,每条指令最多写入64个元素
AOF实时写入流程

AOF重写流程
-
通过fork生成子进程进行重写,重写的子进程并不需要访问老的AOF文件,而是直接根据现有内存数据生成新的AOF文件,生成过程中根据现有数据将多条老数据命令合并成一个。
-
为了防止重写失败,数据丢失,新来的数据依然会将数据写入老的AOF缓冲区中。
-
为了解决老AOF和新AOF在重写过程中数据的一致性问题,会为新的AOF也创建一份缓冲区,当新的数据到来时,同时向新的AOF缓冲区中写入。
即,在重写过程中的数据会写入两份,分别写入旧的AOF和新AOF的缓冲区。 -
完成AOF重写之后
- 当子进程完成对AOF文件重写之后,它会向父进程发送一个完成信号,父进程接到该完成信号之后,会调用一个信号处理函数,该函数完成以下工作:
- 将AOF重写缓存中的内容全部写入到新的AOF文件中;这个时候新的AOF文件所保存的数据库状态和服务器当前的数据库状态一致
- 对新的AOF文件进行改名,原子的覆盖原有的AOF文件;完成新旧两个AOF文件的替换。

在重写期间,由于主进程依然在响应命令,为了保证最终备份的完整性;因此它依然会写入旧的AOF file中,如果重写失败,能够保证数据不丢失。
为了把重写期间响应的写入信息也写入到新的文件中,因此也会为子进程保留一个buf,防止新写的file丢失数据。
重写是直接把当前内存的数据生成对应命令,并不需要读取老的AOF文件进行分析、命令合并。
AOF文件直接采用的文本协议,主要是兼容性好、追加方便、可读性高可认为修改修复。
AOF功能开启
#配置
1.appendonly yes|no
是否开启AOF持久化功能,默认为不开启状态
2.appendfsync always|everysec|no
AOF写数据策略
AOF相关配置
#配置
1.appendfilename filename
AOF持久化文件名,默认文件名未appendonly.aof,建议配置为appendonly-端口号.aof
2.dir
AOF持久化文件保存路径,与RDB持久化文件保持一致即可
RDB和AOF对比
- AOF更安全,可将数据及时同步到文件中,但需要较多的磁盘IO,AOF文件尺寸较大,文件内容恢复相对较慢, 也更完整。
- RDB持久化,安全性较差,它是正常时期数据备份及 master-slave数据同步的最佳手段,文件尺寸较小,恢复数度较快。
从持久化中恢复数据
数据的备份、持久化做完了,我们如何从这些持久化文件中恢复数据呢?如果一台服务器上有既有RDB文件,又有AOF文件,该加载谁呢?
其实想要从这些文件中恢复数据,只需要重新启动Redis即可。我们还是通过图来了解这个流程:

1002

被折叠的 条评论
为什么被折叠?



