目录
什么是持久化:
利用永久性存储介质将数据进行保存,在特定的事件将保存的数据进行恢复的工作机制称为持久化
为什么有持久化?
现实中如果遇到意外断电的情况,放置数据的意外丢失,确保数据的安全性
两种形式
RDB:
将当前数据状态进行保存,快照形式,存储数据结果,存储格式简单,关注点在数据
AOF:
将数据的操作过程进行保存,日志形式,存储操作过程,存储格式复杂,关注带你在数据的操作过程
RDB
启动方式:手动(save)和自动(bgsave)
SAVE启动方式
概念
谁操作的:用户
什么时间:及时(随时进行)
干什么事情:保存数据
保存的数据在哪:
dump.rdb文件中
保存数据命令
# 手动执行一次保存操作
save
SAVE指令相关设置
在redis.config中写
恢复数据
在redis启动的时候就自动加载了
工作原理
数据量大不建立在线上使用,容易阻塞,就有了下面的方式
BGSAVE启动方式
概念
- 谁操作:用户发起指令,redis服务器控制指令执行
什么时间:即时发起,合理时间执行
干什么事情:保存数据
保存的数据在哪:
dump.rdb文件中
配置
在conf文件中进行配置
# 满足限定时间范围内key的变化数量达到指定数量即进行持久化
save second changes
参数:
- second:监控时间范围
- changes:监控key的变化量
范例
# 900秒内发生了一个变化
save 900 1
# 300秒内发生了十个变化
save 300 10
相关配置
工作原理
两种方式对比
方式 | save指令 | bgsave |
---|---|---|
读写 | 同步 | 异步 |
阻塞客户端指令 | 是 | 否 |
额外内存消耗 | 否 | 是 |
启动新进行 | 否 | 是 |
RDB特殊启动形式
- 全量复制
- 服务器运行过程中重启
debug reload
- 关闭服务器时指定保存数据
shutdown save
RDB优缺点
优点
- RDB是一个紧凑的压缩的二进制文件,存储效率高
- RDB内部存储的是redis某个时间点的数据快照,非常适用于数据备份,全量复制等场景
- RDB恢复数据的速度要<>比AOF快很多
- 应用:服务器中每X小时执行BGSAVE备份,并将RDB文件拷贝到远程机器中,用于灾难恢复
缺点 - RDB方式无论是执行指令还是利用配置,无法做到实时持久化,既有较大的可能性丢失数据
- BGSAVE指令每次运行要执行fork操作创建子进程,要牺牲掉一些性能
- redis的众多版本中未进行RDB文件格式的版本统一,有可能出现各版本之间数据格式无法兼容的现象
AOF
为什么要有AOF
由于RDB的一些弊端,它是基于快照思想,每次读写都是全部数据,当数据量巨大时,效率非常低,而且在进行持久化的时候,会fork出一个子进程进行持久化,内存产生额外消耗,因为不是实施存储,所以会带来宕机带来的数据丢失
AOF是什么
以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中命令达到恢复数据的目的,与RDB相比可以简单描述为改记录数据为记录数据产生的过程
主要作用时解决了数据持久化的实时性,目前时Redis持久化的主流方式
AOF写数据过程
流程
那么我们什么时候同步呢?
写数据三种策略
- always(每次)
每次写入操作均同步到AOF文件中,数据零误差,性能较低 - everysec(每秒)
每秒将缓冲区中的指令同步到AOF中,数据准确性较高,性能较高,再系统突然宕机的情况下丢失1秒内的数据 - no(系统控制)
由操作系统控制每次同步到AOF文件的周期,整体过程不可控
存储位置
appendonly.aof文件
AOF功能开启
再redis.conf文件中
# 配置,是否开启AOF持久化功能,默认为不开启状态
appendonly yes|no
#配置AOF写数据策略
appendfsync always|erverysec|no
AOF重写
为什么要由AOF重写
随着命令不断写入AOF,文件会越来越大,为了解决这个问题,Redis引入了AOF重写机制压缩文件体积,AOF文件重写是将Redis进行内的数据转化为些命令同步到新的AOF文件过程中
作用
- 降低磁盘占用量,提高磁盘利用率
- 提高持久化效率,降低持久化写时间,提高IO性能
- 降低数据恢复用时,提高数据恢复效率
重写规则
- 进程内已超时的数据不在写入文件
- 忽略无效指令,重写时使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令
set key4 111
set key4 222
# 只会保留set key4 222
重写方式
手动和自动
- 手动重写
bgrewriteaof
- 自动重写,在redis.conf文件中
auto-aof-rewrite-min-size size atoto-aof-rewrite-percentage percentage
示例:
Redis会记录上次重写时的AOF文件大小,默认配置时当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发
auto-aof-rewrite-percentage 100 (一倍)
auto-aof-rewrite-min-size 64mb
手动重写工作原理
自动重写的触发条件
- 自动重写触发条件设置
auto-aof-rewrite-min-size 64mb atoto-aof-rewrite-percentage 100 (一倍)
- 自动重写触发比对参数(运行指令info persistence获取具体信息)
# aof缓冲有了多少值,如果大于了上面设置的64就重写
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文件重写之后,它会向父进程发送一个完成信号,父进程接到该完成信号之后,会调用一个信号处理函数,该函数完成以下工作:
将AOF重写缓存中的内容全部写入到新的AOF文件中;这个时候新的AOF文件所保存的数据库状态和服务器当前的数据库状态一致;
对新的AOF文件进行改名,原子的覆盖原有的AOF文件;完成新旧两个AOF文件的替换。
当这个信号处理函数执行完毕之后,主进程就可以继续像往常一样接收命令请求了。在整个AOF后台重写过程中,只有最后的“主进程写入命令到AOF缓存”和“对新的AOF文件进行改名,覆盖原有的AOF文件。”这两个步骤(信号处理函数执行期间)会造成主进程阻塞,在其他时候,AOF后台重写都不会对主进程造成阻塞,这将AOF重写对性能造成的影响降到最低。
AOF重写的目的是为了解决AOF文件体积膨胀的问题,使用更小的体积来保存数据库状态,整个重写过程基本上不影响Redis主进程处理命令请求;
RDB与AOF对比
持久化方式 | RDB | AOF |
---|---|---|
占用存储空间 | 小(数量级) | 大(指令级:重写) |
存储速度 | 慢 | 快 |
恢复速度 | 快 | 慢 |
数据安全性 | 会丢失数据 | 依据策略决定 |
资源消耗 | 高/重量级 | 低/轻量级 |
启动优先级 | 低 | 高 |
持久化的场景
用于热点数据,有一定范围,不需要查数据库的,不太需要保存到数据库的
1.抢购,期间万一宕机怎么办?得持久化一下
2.直播的时候,在线人数,万一服务器崩了,需要持久化一下,更新上人数,不能一上来人数为0