Redis持久化
持久化简介
什么是持久化
利用永久性存储介质将数据进行保存,在特定的时间将保存的数据进行恢复的工作机制称为持久化
为什么持久化
防止数据的意外丢失,确保数据安全性
持久化过程保存什么
-
将当前数据状态进行保存以快照形式,存储数据结果,存储格式简单,关注点在数据
-
将数据的操作过程进行保存以日志形式,存储操作过程,存储格式复杂,关注点在数据的操作过程
RDB
RDB其实就是把数据以快照的形式保存在磁盘上。什么是快照呢,你可以理解成把当前时刻的数据拍成一张照片保存下来。
RDB持久化是指在指定的时间间隔内将内存中的数据集快照写入磁盘。也是默认的持久化方式,这种方式是就是将内存中数据以快照的方式写入到二进制文件中,默认的文件名为dump.rdb
既然RDB机制是通过把某个时刻的所有数据生成一个快照来保存,那么就应该有一种触发机制,是实现这个过程。对于RDB来说,提供了三种机制来触发持久化:save、bgsave、自动化
.rdb相关配置
-
dbfilename dump.rdb
说明:设置本地数据库文件名,默认值为dump.rdb,通常设置为dump-端口号.rdb
-
dir
说明:设置存储.rdb文件的路径,通常设置成存储空间较大 的目录,目录名称为data
-
rdbcompression yes
说明:设置存储至本地数据可是否压缩数据,默认为yes,采用LZF压缩,通常默认为开启状态,如果设置为no,可以节省CPU运行时间,但会是存储的文件变得巨大
-
rdbchecksum yes
说明:设置是否进行RDB文件格式校验,该校验过程在写文件和读文件过程均执行,通常默认为开启状态,如果设置为no,可以节约读写过程10%时间消耗,但存在一定的数据损坏风险
模拟数据恢复
步骤:
-
启动redis,插入测试数据后,关停服务
redis-server.exe redis-cli.exe -h 127.0.0.1 -p 6379 set k1 v1
-
备份dump.rdb后删除,重启服务
-
get key查询数据,发现数据已丢失
-
关停服务后还原dump.rdb,重启
-
get key查询数据,数据已恢复
总结:redis基于内存,当服务关闭后内存中数据丢失,只有将数据持久化到磁盘才能在下一次重启服务时依然读到数据,而持久化到磁盘的数据就是存储在dump.rdb中
save指令工作原理
命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止
注意:由于save指令的执行会阻塞当前的redis服务器,这个过程可能持续很长,故生产坏境不建议使用
bgsave指令工作原理
执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求
如图所示,bgsave相较于save,它不会阻塞当前服务器,而是fork出一个子线程去做持久化生成.rdb文件,提高效率
注意:bgsave命令针对save阻塞问题做的优化,故save命令可以弃用
相关配置:
-
stop-writes-on-bgsave-error yes
说明:后台存储过程中如发生错误,是否停止保存操作,通常默认设置为开启状态
问题:当我们忘记手动执行save命令或者bgsave命令去做持久化时怎么办?
redis提供了自动执行持久化的功能,只需在redis.conf配置即可
- 配置 save second changes
- 作用 满足指定时间范围内key的变化数量达到设定值时进行持久化
- 参数 second:监控时间范围 changes:key变化量
例: save 100 10表示100秒内如果有10个值变化则做持久化
注意:
- save配置应结合实际业务情况,频率过高或过低都会出现性能问题
- save配置中second和changes应该是互补关系,尽量不要设置成包含关系
- save配置执行的是bgsave操作
RDB三种方式对比
方式 | save | bgsave | 自动执行 |
---|---|---|---|
读写 | 同步 | 异步 | 实际就是bgsave |
阻塞客户端指令 | 是 | 否 | … |
额外内存消耗 | 否 | 是 | … |
启动新进程 | 否 | 是 | … |
rdb特殊启动方式
-
全量复制
-
服务器运行过程中重启
debug reload
-
关闭服务器是指定保存数量
shutdown save
以上三个指令也会启动RDB生成dump.rdb文件
总结
优点
- .rdb是紧凑压缩的二进制文件,存储效率高
- .rdb内部存储的是在某个时间点的数据快照,适合做数据备份,全量复制等场景
- 恢复数据比AOF快很多
- 服务器每X小时执行bgsave备份,并将.rdb文件拷贝到其他机器,做高可用、灾难恢复
缺点
- 无法做到实时持久,可能会丢失数据,例如配置10秒做一次持久,但在10s内服务器宕机则这段时间的数据将丢失
- bgsave每次fork子进程,消耗性能
- redis众多版本未进行RDB文件的版本统一,可能出现各版本服务之间数据格式无法兼容的问题
AOF
基于RDB的使用弊端,引入AOF持久化,AOF主要解决的就是数据持久化的实时性
AOF(append only file):以独立日志的方式记录每次写命令,重启时再执行AOF文件中的命令达到活肤数据的目的,与RDB相比将记录数据改为记录数据产生的过程
AOF的主要作用就是解决数据持久化的实时性,目前医师redis持久化的主流方式
AOF写数据过程
客户端执行一条写操作时,redis服务器会将命令写入AOP命令缓存区,最后从缓存区中持久化到AOF文件中
问题:何时去将缓存区数据写入.aof文件中呢?
AOF三种写数据策略:
-
always每次
每次写命令均同步到AOF文件中,数据零误差,性能低
-
everysec每秒
每秒执行一次同步,数据准确性较高,性能较高
在系统突然宕机的情况下丢失1秒内的数据
-
no系统控制
操作系统控制每次同步到AOF文件的周期,整体过程不可控
AOF功能开启
redis.conf配置修改
-
appendonly yes|no # 是否开启AOF持久化功能,默认是关闭的
-
appendfsync always|everysec|no #AOF写数据策略
-
appendfilename filename #AOF文件名,默认appendonly.aof,建议appendonly-端口号.aof
-
dir # aof文件保存路径
AOF重写
随着命令不断写入aof,文件越来越大,为解决该问题,redis引入了AOF重写机制来压缩文件体积。aof文件重写是将redis进程内的数据转化为写命令同步到新aof文件的过程,即若干条命令执行结果合并成最终的结果数据对应的指令进行记录
例:多次incr num会被合成为最终结果对应的一条指令
重写的作用
- 降低磁盘占用量,提高磁盘利用率
- 提高持久化效率,降低持久化写时间,提高IO性能
- 降低数据恢复勇士,提高恢复效率
AOF重写规则
-
进程内已超时数据不再写入(数据都没了,就必要再持久化了)
-
忽略无效指令,只保留最终数据的写入命令
如del key,get key,set k1 v1(无效)、set k1 v2等
-
对统一数据多条指令合并为一条命令
例:lpush k1 a、lpush k1 b合并为lpush k1 a b
为防止数据量过大造成客户端缓冲区溢出,对list、set、hash、zset等类型,每条指令最多写入64个元素
重写方式
-
手动重写
bgrewriteaof # 后台重写aof
原理:和bgsave类似,会创建一个子进程去重写AOF文件
-
自动重写
auto-aof-rewrite-min-size size # 配置重写最小触发条件
auto-aof-rewrite-percentage percentage #自动重写百分比
-
自动重写触发对比参数(运行info Persistence获取具体信息)
aof_current_size #当前缓冲大小
aof_base_size #基础大小
-
触发条件
aof_current_size > auto-aof-rewrite-min-size
aof_current_size-aof_base_size / aof_base_size >= auto-aof-rewrite-percentage
-
AOF重写流程
RDB与AOF的区别
持久化方式 | RDB | AOF |
---|---|---|
占用存储空间 | 小(数据级:压缩) | 大(指令级:重写) |
存储速度 | 慢 | 快 |
恢复速度 | 快 | 慢 |
数据安全性 | 会丢失数据 | 依据策略决定 |
资源消耗 | 高/重量级 | 低/轻量级 |
启动优先级 | 低 | 高 |
两种持久化如何选择?
- 对数据非常敏感,建议使用默认的AOF持久化方案
- AOF持久化策略使用everysecond,每秒fsync一次,该策略保持良好的处理性能,最多丢失0-1秒内的数据
- AOF体积较大,且恢复速度较慢
- 数据呈现阶段有效性,建议使用RDB
- 数据可以良好的做到阶段内无丢失,且恢复速度较快,阶段点数据恢复通常采用RDB方案
- 利用RDB实现紧凑的数据持久化会使redis降的很低
综合比对:
- RDB和AOF的选择实际上是在做一种权衡,每种都有利有弊
- 如不能承受分钟以内的数据丢失,对业务数据敏感则选用AOF
- 如能承受分钟以内的数据丢失,且追求大数据集的恢复速度,选用RDB
- 灾难恢复选用RDB
- 双保险策略,同时开启RDB和AOF,重启后,redis优先使用AOF来恢复数据,降低数据丢失量
持久化应用场景
应用于抢购、秒杀等高并发场景下或者换个角度,redis中的数据没有在数据库中存储该考虑做持久化