- 一、Redis持久化概述
- 二、
快照(Snapshot)
也称为RDB
持久化方式- 1、RDB持久化特点
- 2、快照生成方式
- 2.1 客户端方式之
BGSAVE
(并行操作) - 2.2 客户端方式之
SAVE
(串行操作) - 2.3 服务器
配置方式
之满足配置自动触发
- 2.4 服务器接收客户端
shutdown指令
- 2.1 客户端方式之
- 3、配置生成快照名称和位置
- 4、
RDB(快照)持久化的缺点
- 三、AOF 只追加日志文件
- 1、AOF持久化的特点
- 2、开启AOF持久化
- 3、日志追加频率
- always (谨慎使用)
everysec (推荐)
- no (不推荐)
- 4、修改同步频率
- 四、
AOF文件的重写
- 重写原理
- 五、持久化总结
跳转到目录 Redis
的高性能
是由于其将所有数据
都存储
在了内存
中,为了使Redis在重启之后仍能保证数据不丢失
,需要将数据从内存中同步到硬盘中,这一过程就是持久化
。Redis支持两种方式的持久化,一种是 RDB方式
,一种是 AOF方式
。可以单独使用其中一种或将二者结合使用。
RDB持久化
(默认支持,无需配置) 该机制是指在指定的时间间隔
内将内存中的数据集快照
写入磁盘。AOF持久化
该机制将以日志
的形式记录服务器所处理的每一个写操作
,在Redis服务器启动之初会读取该文件来重新构建redis数据库,以保证启动后数据库中的数据
是完整的。- 无持久化 我们可以通过配置的方式禁用Redis服务器的持久化功能,这样我们就可以将Redis视为一个功能加强版的memcached了。
redis可以同时使用RDB和AOF
快照(Snapshot)
也称为RDB
持久化方式
跳转到目录
1、RDB持久化特点- 这种方式可以将
某一时刻
的所有数据
都写入硬盘
中,当然这也是redis的默认开启持久化方式,保存的文件是以.rdb
形式结尾的文件因此这种方式也称之为RDB方式
。
跳转到目录
- 客户端方式:
BGSAVE
和SAVE
指令 - 服务器配置自动触发
BGSAVE
(并行操作)
-
a. 客户端可以使用
BGSAVE命令
来创建一个快照
,当redis服务器
接收到客户端
的BGSAVE
命令时,redis会调用fork¹
来创建一个子进程
,然后子进程
负责将快照写入磁盘中,而父进程则继续处理命令请求。名词解释: fork,当一个进程创建子进程的时候,底层的操作系统会创建该进程的一个副本,在类unix系统中创建子进程的操作会进行优化:在刚开始(没有set操作)的时候,父子进程共享相同内存,直到父进程或子进程对内存进行了写(set操作)之后,对被写入的内存的共享才会结束服务
SAVE
(串行操作)
- b.客户端还可以使用
SAVE命令
来创建一个快照
,接收到SAVE命令的redis服务器在快照创建完毕之前将不再响应任何其他的命令
- 注意: SAVE命令并
不常用
,使用SAVE命令在快照创建完毕之前,redis处于阻塞状态
,无法对外服务(写操作)
配置方式
之满足配置自动触发
这里和MySQL的Redo机制
很类似,它是用来持久化事务
相关
- 如果用户在
redis.conf
中设置了save配置选项
,redis会在save选项条件满足之后自动触发一次BGSAVE命令, 如果设置多个save配置选项,当任意一个save配置选项条件满足,redis也会触发一次BGSAVE命令
- 表示
900S(15分钟)
, key发生1次变化, 就触发一次 bgsave命令, 持久化一次 - 表示
300S(5分钟)
, key发生10次变化, 就触发一次bgsave命令, 持久化一次 - 表示
60S(1分钟)
, key发生10000次变化, 就触发一次bgsave命令, 持久化一次
上面自动触发的规则: 标明key改变的越频繁, 触发快照持久化到硬盘的时间就越短;
shutdown指令
- 当
redis服务器
接收到redis客户端
发来的shutdown指令
关闭服务器时,会执行一个save命令
,阻塞所有的客户端,不再执行客户端执行发送的任何命令,并且在save命令执行完毕之后关闭服务器
跳转到目录
1.修改生成快照名称dbfilename dump.rdb
dir ./
RDB(快照)持久化的缺点:
跳转到目录
- 如果你想保证数据的
高可用性
,即最大限度的避免数据丢失
,那么RDB将不是一个很好的选择
。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
(还没有到达指定时间作持久化)- 比如说, 我们设置
5分钟
修改了13+
个key, 此时在2分钟
的时候就修改了11
个key, 但是此时还差3分钟
, 才能作持久化
操作, 此刻,redis服务器
挂了, 那就代表, 前2分钟修改的那11个key, 数据就丢失
了
- 比如说, 我们设置
其中,上面配置的是RDB方式数据持久化时机:
关键字时间(秒)key修改数量解释save9001每900秒(15分钟)至少有1个key发生变化,则dump内存快照save30010每300秒(5分钟)至少有10个key发生变化,则dump内存快照save6010000每60秒(1分钟)至少有10000个key发生变化,则dump内存快照 AOF 只追加日志文件跳转到目录
1、AOF持久化的特点- 这种方式可以将所有
客户端
执行的(set)写命令
记录到日志文件
中,AOF持久化
会将被执行的写命令写到AOF的文件末尾,以此来记录数据发生的变化
- 想要恢复内存中的数据, 只要redis从头到尾执行一次AOF文件所包含的所有写命令,就可以恢复
AOF文件的记录的数据集
.(将写命令原封不动的写到aof的文件, 下次再从新执行就恢复了数据) - 该机制将以
日志
的形式记录服务器所处理的每一个写操作
,在Redis服务器启动之初会读取该文件来重新构建redis数据库,以保证启动后数据库中的数据
是完整的。
跳转到目录 在redis的默认配置(redis.conf)
中AOF持久化机制
是没有开启
的,需要在配置中开启。
开启AOF持久化
- a. 修改
appendonly yes
开启持久化 - b. 修改
appendfilename "appendonly.aof"
指定生成文件名称
日志追加频率
跳转到目录
3.1、always (谨慎使用)
- 说明: 每当我们执行(set)写操作, redis都要同步写入硬盘,严重降低redis速度
- 解释: 如果用户使用了
always
选项,那么每个redis写命令都会被写入硬盘
,从而将发生系统崩溃时出现的数据丢失减到最少
; 遗憾的是,因为这种同步策略
需要对硬盘进行大量的写入操作
,所以redis处理命令的速度会受到硬盘性能的限制; - 注意:
转盘式硬盘
在这种频率下200左右个命令/s ;固态硬盘(SSD)
几百万个命令/s; - 警告: 使用SSD用户请谨慎使用always选项,这种模式不断写入少量数据的做法有可能会引发严重的写入放大问题,导致将固态硬盘的寿命从原来的几年降低为几个月。
everysec (推荐)
- 说明: 每秒执行一次同步, 显式的将多个写命令同步到磁盘
- 解释: 为了兼顾
数据安全
和写入性能
,用户可以考虑使用everysec
选项,让redis每秒一次的频率对AOF文件进行同步
,redis每秒同步一次AOF文件时性能和不使用任何持久化特性时的性能相差无几,而通过每秒同步一次AOF文件
, redis可以保证,即使系统崩溃,用户最多丢失一秒之内产生的数据
。(因为下次在打开redis服务, 就会将aof中的所有写命令执行, 恢复数据, 由于每一秒都会将写命令同步aof中, 即使丢失, 也就丢失1s的数据)
no (不推荐)
- 说明: 由操作系统决定何时同步
- 解释:最后使用
no
选项,将完全由操作系统决定什么时候同步AOF日志文件
,这个选项不会对redis性能带来影响但是系统崩溃时,会丢失不定数量的数据,另外如果用户硬盘处理写入操作不够快的话,当缓冲区被等待写入硬盘数据填满时,redis会处于阻塞状态,并导致redis的处理命令请求的速度变慢。
跳转到目录
1.修改日志同步频率- 修改
appendfsync everysec|always|no
指定
上述配置为aof持久化的时机,解释如下:
关键字持久化时机解释appendfsyncalways每执行一次更新命令,持久化一次appendfsynceverysec每秒钟持久化一次appendfsyncno不持久化 四、AOF文件的重写跳转到目录
1、AOF(日志文件)持久化的缺点:
AOF的方式
也同时带来了另一个问题, 持久化文件会变的越来越大。例如我们调用incr test命令100次,文件中必须保存全部的100条命令,其实有99条都是多余的
。因为要恢复数据库的状态其实文件中保存一条set test 100
就够了。- 为了
压缩aof的持久化文件
Redis提供了AOF重写(ReWriter)机制
。
AOF重写
- 用来在一定程度上
减小AOF文件的体积
跳转到目录
3.1、客户端方式触发重写 bgrewriteaof命令- 执行
BGREWRITEAOF命令
不会阻塞redis的服务
自动触发重写aof
- 配置
redis.conf
中的auto-aof-rewrite-percentage
选项 , 下图。 - 如果设置
auto-aof-rewrite-percentage值为100
和auto-aof-rewrite-min-size 64mb
,并且启用的AOF持久化时
,那么当AOF文件体积大于64M,并且AOF文件的体积比上一次重写之后体积大了至少一倍(100%)时,会自动触发,如果重写过于频繁,用户可以考虑将auto-aof-rewrite-percentage设置为更大
跳转到目录
- 注意:
重写aof文件
的操作,并没有读取旧的aof文件
,而是将整个内存中的数据库内容用命令的方式重写了一个新的aof文件, 替换原有的文件这点和快照有点类似。
- redis调用
fork
,现在有父子两个进程,子进程
根据内存中的数据库快照
,往临时文件中写入重建数据库状态的命令 父进程
继续处理client请求
,除了把写命令写入到旧的aof文件
中。同时把收到的写命令缓存
起来。这样就能保证如果子进程重写失败的话并不会出问题。- 当子进程把快照内容写入已命令方式写到临时文件中后,
子进程发信号通知父进程
。然后父进程把缓存的写命令也写入到临时文件。 - 现在父进程可以使用
临时文件
替换老的aof文件
,并重命名,后面收到的写命令也开始往新的aof文件中追加
。
跳转到目录
-
两种持久化方案既可以
同时使用(aof),
又可以单独使用
,在某种情况下也可以都不使用,具体使用那种持久化方案取决于用户的数据和应用决定
。 -
无论使用
AOF
还是快照机制
持久化,将内存中的数据持久化到硬盘都是有必要
的,除了持久化外,用户还应该对持久化的文件进行备份
(最好备份在多个不同地方)。
-
对数据非常敏感,建议使用默认的AOF
持久化方案
- AOF持久化策略使用everysecond,每秒钟fsync一次。该策略redis仍可以保持很好的处理性能,当出现问题时,最多丢失0-1秒内的数据。
- 注意:由于AOF文件存储体积较大,且恢复速度较慢
-
数据呈现阶段有效性,建议使用RDB持久化方案
- 数据可以良好的做到阶段内无丢失(该阶段是开发者或运维人员手工维护的),且恢复速度较快,阶段 点数据恢复通常采用RDB方案
- 注意:利用RDB实现紧凑的数据持久化会使Redis降的很低
-
综合比对
- RDB与AOF的选择实际上是在做一种权衡,每种都有利有弊
- 如不能承受数分钟以内的数据丢失,对业务数据非常敏感,选用AOF
- 如能承受数分钟以内的数据丢失,且追求大数据集的恢复速度,选用RDB
- 灾难恢复选用RDB
- 双保险策略,同时开启 RDB 和 AOF,重启后,Redis优先使用 AOF 来恢复数据,降低丢失数据