一、Redis 持久化
redis 的数据全部在内存中,如果突然宕机,数据就会全部丢失,因此需要持久化来保证 Redis 的
数据不会因为故障而丢失,redis 重启的时候可以重新加载持久化文件来恢复数据
Redis的持久化主要有4种方式:
- aof
- rdb
- aof-rewrite
- aof-rdb混用
核心知识点:
rdb与aof区别
aof-rewrite解决aof什么问题
aof-rdb混用解决aof-rewrite什么问题
二、aof
append only file
aof 日志存储的是 Redis 服务器的顺序指令序列,aof 日志只记录对内存修改的指令记录
1、aof的执行流程
1.执行命令
2.会判断是否开启aof,
3.如果开启的话,就将命令写入aof buffer中
4.最后根据策略,将aof buffer中的数据刷入磁盘中
需要了解的内容
刷盘策略是什么?
持久化什么内容?这条命令的协议数据
如何恢复(具体原理)?加载保存的协议数据,解析协议数据成命令,重新执行这些命令
2、redis.conf中配置aof
在redis.conf中由aof的相关配置
是否开启aof
appendonly为是否开启aof,如果如yes,则说明开启aof。默认是关闭的
appendonly no
aof的保存文件的前缀名
保存的aof文件都以这个为前缀
appendfilename "appendonly.aof"
刷入磁盘的策略
everysec:定时器使得每秒都会刷入磁盘(每秒都进行持久化)
always:每执行一个命令都会刷入磁盘(持久化)
no:交由系统刷盘
# appendfsync always appendfsync everysec # appendfsync no
3、aof持久化的内容是什么
设置相应的redis.conf(自己取个名字,比如我取了redis_aof.conf),通过这个conf去运行redis-server
dir /home/xuheding/redis-data/default port 6379 daemonize yes appendonly yes appendfsync everysec save ""
运行
redis-server redis_aof.conf
可以发现当前目录下,多了一些aof文件(appendonly.aof暂时是空的)
然后进行redis-cli,随便输入一个命令
然后可以看到appendonly.aof中的内容了
持久化的内容是这条命令的协议数据
4、aof的缺点
随着时间越长,aof 日志会越来越长,如果 redis 重启,重放整个 aof 日志会非常耗时,导致
redis 长时间无法对外提供服务;
三、aof rewrite
1、原理
aof 持久化策略会持久化所有修改命令;里面的很多命令其实可以合并或者删除;
aof rewrite 在 aof 的基础上,满足一定策略则 fork 进程,根据当前内存状态,转换成一系列
的 redis 命令,序列化成一个新的 aof 日志文件中,序列化完毕后再将操作期间发生的增量 aof 日
志追加到新的 aof 日志文件中国你,追加完毕后替换旧的 aof 日志文件;以此达到对 aof 日志瘦
身的目的;
注意:aof rewrite 开启的前提是开启 aof
由于aof的缺点,aof日志比较长,读取过慢。有些命令其实可以合并或者删除
比如
下面这两条命令完全可以一起删除
lpush list dog lpop list dog
像下面三条命令,分开执行效率慢,可以合并成一条lpush list p1 p2 p3
lpush list p1 lpush list p2 lpush list p2
在aof中除了网络io,还会有磁盘io,磁盘io会占用主线程,会影响性能,而在aof rewrite中,通过fork另起一个进程的方式,通过子进程,对数据进行磁盘io操作,从而不会影响主进程。在主进程修改时,也不会对该子进程的数据产生影响(写时复制)
子进程复写结束后,通过pipe管道去通知主进程复写完了,主进程之后添加的命令,都时在复写后的aof文件的后面添加的。
2、配置
# 开启 aof appendonly yes # 开启 aof复写 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb # 关闭 混合持久化 aof-use-rdb-preamble no # 关闭 rdb save ""
3、策略
这里设置了最小aof-rewrite内存大小,当大于等于64mb的时候就会进行一次复写
而aof-rewrite-percentage 100表示,下一次复写就是原来两倍大小,比如第一次aof文件大小64mb复写,第二次就是128mb,第三次256mb,以此类推
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
4、缺点
aof复写在 aof 基础上实现了瘦身,但是 aof 复写的数据量仍然很大;加载会非常慢
四、rdb
1、原理
基于 aof 或 aof 复写文件大的缺点,rdb 是一种快照持久化;它通过 fork 主进程,在子进程中将
内存当中的数据键值对按照存储方式持久化到 rdb 文件中;rdb 存储的是经过压缩的二进制数
据;
将内存中的数据直接写入磁盘,读取得时候直接读入内存就行了
2、配置
在使用rdb的时候要把aof,和aof-rewrite都关闭
要开启rdb,首先要把save ”“
注释掉
# 关闭 aof 同时也关闭了 aof复写 appendonly no # 关闭 aof复写 auto-aof-rewrite-percentage 0 # 关闭 混合持久化 aof-use-rdb-preamble no # 开启 rdb 也就是注释 save "" # save "" save 3600 1 save 300 100 save 60 10000
3、策略
save 3600 1
表示3600秒(1小时)内有1次修改数据
save 300 100
表示300秒内有100次修改数据
save 60 10000
表示60秒内有10000次修改数据
上述save语句中,满足任意一个就fork子进程进行rdb写
4、缺点
若采用 rdb 持久化,一旦 redis 宕机,redis 将丢失一段时间的数据;
RDB 需要经常 fork 子进程来保存数据集到硬盘上,当数据集比较大的时候,fork 的过程是非常耗
时的,可能会导致 Redis 在一些毫秒级内不能响应客户端的请求。如果数据集巨大并且 CPU 性能
不是很好的情况下,这种情况会持续1秒,AOF 也需要 fork,但是你可以调节重写日志文件的频率
来提高数据集的耐久度
五、混合持久化
原理
从上面知道,rdb 文件小且加载快但丢失多,aof 文件大且加载慢但丢失少;混合持久化是吸取
rdb 和 aof 两者优点的一种持久化方案;aof 复写的时候实际持久化的内容是 rdb,等持久化后,
持久化期间修改的数据以 aof 的形式附加到文件的尾部;
混合持久化实际上是在 aof rewrite 基础上进行优化;所以需要先开启 aof rewrite;
复写的流程,是通过rdb的数据方式存储的(直接存储 数据)
也就是持久化文件中,前面部分是rdb数据,后面是aof数据
配置
# 开启 aof appendonly yes # 开启 aof复写 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb # 开启 混合持久化 aof-use-rdb-preamble yes # 关闭 rdb save "" # save 3600 1 # save 300 100 # save 60 10000
六、应用
- MySQL 缓存方案中,redis 不开启持久化,redis 只存储热点数据,数据的依据来源于
MySQL;若某些数据经常访问需要开启持久化,此时可以选择 rdb 持久化方案,也就是允许
丢失一段时间数据; - 对数据可靠性要求高,在机器性能,内存也安全 (fork 写时复制 最差的情况下 96G)的情况
下,可以让 redis 同时开启 aof 和 rdb,注意此时不是混合持久化;redis 重启优先从 aof 加
载数据,理论上 aof 包含更多最新数据;如果只开启一种,那么使用混合持久化; - 在允许丢失的情况下,亦可采用主redis不持久化(96G 90G),从redis进行持久化;
- 伪装从库;
七、数据安全策略
问题:拷贝持久化文件是否安全? 是安全的,持久化 文件一旦被创建, 就不会进行任何修改。 当服务器要创建一个新的持久化文件 时, 它先将文件的内容保存在一个临时文件里面, 当临时文件写入完毕时, 程序才使用 rename(2) 原子地用临时文件替换原来的持久化文件。
数据安全要考虑两个问题:
- 节点宕机(redis 是内存数据库,宕机数据会丢失)
- 磁盘故障
- 创建一个定期任务(cron job), 每小时将一个 RDB 文件备份到一个文件夹, 并且每天将一个
RDB 文件备份到另一个文件夹。 - 确保快照的备份都带有相应的日期和时间信息, 每次执行定期任务脚本时, 使用 find 命令来删除
过期的快照: 比如说, 你可以保留最近 48 小时内的每小时快照, 还可以保留最近一两个月的每
日快照。 - 至少每天一次, 将 RDB 备份到你的数据中心之外, 或者至少是备份到你运行 Redis 服务器的物理
机器之外。
当既有aof又有rdb文件的时候,会默认读取aof文件(因此aof文件最新)
如果想要读取rdb文件,那么可以将aof文件改名作为备份用