redis的持久化方式-RDB和AOF两种持久化机制
Redis是基于内存的非关系型K-V数据库,既然它是基于内存的,如果Redis服务器挂了,数据就会丢失。为了避免数据丢失了,Redis提供了持久化,即把数据保存到磁盘。
持久化文件加载流程如下:
1.RDB—Redis默认的持久化方式
在指定的时间间隔内将内存中的数据集快照写入磁盘
RDB 又分为两种:
- 一种是同步的,调用 save 命令即可触发 redis 进行 RDB 文件生成备份,但是这是一个同步命令,在备份完成之前,redis 服务器不响应客户端任何请求。
- 另一种是异步的,调用 bgsave 命令,redis 服务器 fork 一个子进程进行 RDB 文件备份生成,与此同时,主进程依然可以响应客户端请求。
两种触发方式:手动触发(save命令),自动触发(bgsave命令,推荐)
save命令:阻塞当前redis直到rdb持久化完成。若内存实例较大,会造成长时间阻塞,线上环境不建议使用。
bgsave命令:redis进程执行fork命令创建子进程来完成持久化,阻塞时间短(微秒级),save命令的优化。
bgsave触发的条件:
1.在redis-cli中执行shutdown关闭redis服务时,如果没有开启aof持久化,自动执行bgsave命令
2.redis.conf中save m n 若redis在m秒内有n次命令执行则触发
3.从节点刚上线时,触发主节点bgsave命令,然后将生成的rdb文件发送给从节点完成全量复制
fork是linux系统的调用:在当前进程中,fork一个子进程,子进程最初与主进程是共享一份内存区域的。由于主进程不断进行数据的写操作,与子进程存在并发冲突问题。此时,redis采用写时复制技术(cow):
当主进程写操作时,首先会复制一份将要涉及写操作的内存页。然后主进程在新复制的内存页上进行写操作,原有内存页继续供子进程持久化
相关配置
1.save 触发bgsave
save 900 1 # 900秒内执行一次set操作 则持久化1次
save 300 10 # 300秒内执行10次set操作,则持久化1次
save 60 10000 # 60秒内执行10000次set操作,则持久化1次
2.在redis.conf文件中有设置 默认是文件名和保存路径(默认是 当前启动目录下 就是执行启动命令的目录)
- stop -writes -on-bgsave-er ror当Redis无法写入磁盘的话(磁盘满了),直接关掉Redis的写操作。推荐yes.
4.rdbcompression
对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。
如果你不想消耗CPU来进行压缩的话,可以设置为关闭此功能。推荐yes.
5.rdbchecksum检查完整性
在存储快照后,还可以让redis使用CRC64算法来进行数据校验,校验 RDB 文件是否发生损坏
但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能推荐yes.
优缺点
- 优点:
l 灵活设置备份频率和周期。
l 适合大规模的数据恢复,非常适合冷备份,对于灾难恢复而言,RDB 是非常不错的选择。保存在其他云存储上
l 对数据完整性和一致性要求不高更适合使用
l 节省磁盘空间
l 性能最大化,可以让 Redis 保持高性能。
l 恢复速度快,相比于 AOF 机制,RDB 的恢复速度更更快,更适合恢复数据,特别是在数据集非常大的情况。
- 缺点:
l Fork的时候,内存中的数据被克隆了一份,大致2倍的膨胀性需要考虑
l 在备份周期在一定间隔时间做一次备份,所以如果Redis意外down掉的话,就会丢失最后一次快照后的所有修改
l 如果数据集很⼤,fork() 可能很耗时,并且如果数据集很⼤且CPU 性能不佳,则可能导致 Redis 停⽌为客⼾端服务⼏毫秒甚⾄⼀秒钟。
所以,RDB 建议在业务低时执行,例如在半夜执行。
2.AOF(Append Only File)
以日志的形式来记录每个写操作(增量保存),将Redis执行过的所有写指令记录下来(读操作不记录), 只许追加文件但不可以改写文件。
默认不开启,改为yes 打开。保存的路径与rdb一样。
AOF和RDB同时开启,系统默认取AOF的数据(数据不会存在丢失)
数据备份恢复和rdb一样: 保存一份文件,当发生错误后,copy过来, 重启redis
异常恢复
修改默认的appendonly no,改为yes
如遇到AOF文件损坏,通过/usr/local/bin/redis-check-aof–fix appendonly.aof进行恢复
备份被写坏的AOF文件
恢复:重启redis,然后重新加载
相关配置
AOF同步频率设置
appendfsync always
始终同步,每次Redis的写入都会立刻记入日志;性能较差但数据完整性比较好
appendfsync everysec
每秒同步,每秒记入日志一次,如果宕机,本秒的数据可能丢失。
appendfsync no
redis不主动进行同步,把同步时机交给操作系统。
Rewrite压缩
重写压缩机制,AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩, 只保留可以恢复数据的最小指令集
Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发
如果Redis的AOF当前大小>= base_size +base_size*100% (默认)且当前大小>=64mb(默认)的情况下,Redis会对AOF进行重写。
AOF持久化流程
(1)客户端的请求写命令会被append追加到AOF缓冲区内;
(2)AOF缓冲区根据AOF持久化策略[always,everysec,no]将操作sync同步到磁盘的AOF文件中;(默认是everysec)
(3)AOF文件大小超过重写策略或手动重写时,会对AOF文件rewrite重写,压缩AOF文件容量;
(4)Redis服务重启时,会重新load加载AOF文件中的写操作达到数据恢复的目的;
优缺点
优
-
备份机制更稳健,丢失数据概率更低。
-
可读的日志文本,通过操作AOF稳健,可以处理误操作。
缺
-
比起RDB占用更多的磁盘空间。
-
恢复备份速度要慢。
-
每次读写都同步的话,有一定的性能压力。
-
存在个别Bug,造成恢复不能。
官方推荐两个都启用。
如果对数据不敏感,可以选单独用RDB。
不建议单独用 AOF,因为可能会出现Bug。
如果只是做纯内存缓存,可以都不用。
同时开启时
3.RDB-AOF混合持久化
# When rewriting the AOF file, Redis is able to use an RDB preamble in the
# AOF file for faster rewrites and recoveries. When this option is turned
# on the rewritten AOF file is composed of two different stanzas:
#
# [RDB file][AOF tail]
#
# When loading Redis recognizes that the AOF file starts with the "REDIS"
# string and loads the prefixed RDB file, and continues loading the AOF
# tail.
aof-use-rdb-preamble yes
开启后
Redis服务器 在执行 AOF重写操作时,就会像执行BGSAVE命令那样,根据数据库当前的状态 生成出 相应的RDB数据,并将这些数据 写入 新建的AOF文件中,至于那些 在AOF重写开始之后 执行的Redis命令,则会继续以协议文本的方式 追加到 新AOF文件的末尾,即已有的RDB数据的后面
- 在该模式下,AOF 重写产生的文件将同时包含 RDB 格式的内容和 AOF 格式的内容,该文件的前半段是 RDB 格式的全量数据,而后半段是 Redis 命令格式的增量数据
当一个支持RDB-AOF混合持久化模式的Redis服务器启动并载入AOF文件时,它会检查AOF文件的开头是否包含了RDB格式的内容