持久化简介
什么是持久化
利用永久性存储介质将数据进行保存,在在特定的时间将保存的数据进行恢复的工作机制称为持久化。
为什么要持久化
防止数据意外丢失,保证数据安全。
持久化的功能
Redis是内存数据库,数据都是存储在内存中,为了避免进程退出导致数据的永久丢失,需要定期将Redis中的数据以某种形式(数据或命令)从内存保存到硬盘;当下次Redis重启时,利用持久化文件实现数据恢复。除此之外,为了进行灾难备份,可以将持久化文件拷贝到一个远程位置。
Redis持久化类型
RDB持久化和AOF持久化:前者将当前数据保存到硬盘,后者则是将每次执行的写命令保存到硬盘(类似于MySQL的binlog)。由于AOF持久化的实时性更好,即当进程意外退出时丢失的数据更少,因此AOF是目前主流的持久化方式,不过RDB持久化仍然有其用武之地。
RDB持久化
RDB概念
RDB持久化是将当前进程中的数据生成快照保存到硬盘(因此也称作快照持久化),保存的文件后缀是rdb;当Redis重新启动时,可以读取快照文件恢复数据。
RDB的启动方式---save
手动执行
命令:save
命令可以保存数据到硬盘,默认生成dump.rdb快照文件。
save指令相关配置
- dbfilename dump.rdb
设置本地数据库文件名,默认为dump.rdb。通常设置为dump-端口号.rdb
- dir
设置.rdb 文件的路径,通常设置存储空间较大的目录中,目录名为data - rdbcompression yes
设置存储至本地数据库时是否压缩,通常设置开启状态。 - rdbchecksum yes
设置是否进行RDB文件格式校验,开启会消耗一定的性能,不开启存储会存在数据损坏风险,通常设置为开启状态
redis为单线程任务执行序列,save指定的执行会阻塞当前redis服务器,直到当前rdb过程完成位置,线上环境不建议使用。
后台执行
命令:bgsave
,手动启动后后台执行,不会立即操作。由redis 调用fork函数生成子进程进行save操作,生成RDB文件。
bgsave指令相关配置
- 参考save指令相关配置
- stop-writes-on-bgsave-error yes
后台存储过程中如果出现错误现象,是否停止保存操作,通常设置为开启状态
bgsave是针对save阻塞问题做的优化,redis内部所有涉及到RDB操作都采用bgsave的方式,save命令可以放弃使用。
自动执行
相关配置
save second changes
- 作用:满足限定时间范围内key的变化数量达到指定数量即进行持久化。
- second:监控时间范围,changes:监控key的变化量。
# bgsave
# 900秒:15分钟内变化一个存一次
save 900 1
# 300秒 5分钟内变了10个就存一次
save 300 10
# 1分钟内1万个变化存一次
save 60 10000
save配置要根据实际业务情况进行设置,频度过高或过低都会出现性能问题,对于second与changes设置通常具有互补关系,尽量不要设置行包含性关系,save配置实际是执行的bgsave操作。
RDB持久化三种方式对比
方式 | save | bgsave |
---|---|---|
读写 | 同步 | 异步 |
阻塞客户端指令 | 是 | 否 |
额外内存消耗 | 否 | 是 |
启动新进程 | 否 | 是 |
RDB优点
- RDB是一个紧凑压缩的二进制文件,存储效率高
- RDB内部存储的是redis在某个时间点的数据快照,非常适合用于数据备份,全量复制等场景
- RDB数据恢复比AOF快
- 应用:服务器中每X小时执行bgsave备份,并将RDB文件拷贝到远程机器中,用于灾难恢复
RDB 缺点
- RDB方式无论是执行指令还是配置,无法做到实时持久化,具有较大可能性丢失数据
- bgsave每次执行都要fork操作创建子进程,要牺牲一些性能
- Redis各版本中RDB文件格式不统一,可能出现各版本之间数据格式无法兼容的现象
AOF持久化
RDB存储的弊端
- rdb存储数据量较大,效率较低,基于快照思想,每次独写都是全部数据,当数据量过大时,影响效率。
- bgsave 基于fork创建子进程,会产生额外消耗
- 突然宕机会影响数据丢失的风险
解决思路
不写全数据,仅记录部分数据。(AOF,不记录数据,对所有操作进行记录,降低丢失数据风险。)
AOF 概念
- AOF(append only file)持久化:以独立日志的方式记录每次写命令,启动时再重新执行AOF文件中命令达到恢复数据的目的。与RDB相比可以简单描述为
改记录数据为记录数据产生的过程
。 - AOF的主要作用时解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。
(RDB和AOF到底用哪个呢?建议优先使用AOF。)
AOF写数据的三种策略
always(每次)每次写入操作均同步到AOF文件中,数据零误差,性能较低。不建议使用
everysec(每秒)每秒将缓冲区中的指令同步到AOF文件中,数据准确性较高,性能较高,突然宕机的情况下最多丢失1秒内的数据。 建议使用
no(系统控制)由操作系统控制每次同步到AOF文件的周期,整体过程不可控。
AOF功能开启
#appendonly 是否开启AOF持久化功能,默认no
appendonly yes
#AOF写数据的策略
appendfsync always|everysec|no
#自定义文件名
appendfilename filename
# dir 文件路径,与RDB持久化文件保持一致就可以了
AOF重写
随着命令不断写入AOF,文件会越来越大,为了解决这个问题,redis引入了AOF重写机制压缩文件体积。AOF文件重写是将Redis进程内的数据转化为写命令同步到AOF文件的过程。简单说就是将同一个数据若干个命令执行结果转化成最终结果数据对应的指令进行记录。
作用
- 降低磁盘占用量,提高磁盘利用率
- 提高持久化效率,降低持久化写时间,提高IO性能
- 降低数据恢复用时,提高数据恢复效率
AOF重写规则
- 进程内已超时的数据不再写入文件
- 忽略无效指令,重写时使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令
如del key1、hdel key2、srem key3、set key4 111、set key4 222等 - 对同一数据的多条写命令合并为一条命令。
为防止数据量过大造成缓冲区溢出,对list set hash zset等类型,每条最多写入64个元素
重写配置
-
手动重写
bgrewriteaof
-
自动重写
#条件设置 auto-aof-rewrite-min-size size auto-aof-rewrite-percentage percent # 自动重写触发对比参数(info persistence获取具体信aof_base_size息) aof_current_size aof_base_size #自动写触发条件 aof_current_size>uto-aof-rewrite-min-size (aof_current_size-aof_base_size)/aof_base_size>=auto-aof-rewrite-percentage percent
-
aof常用配置
#是否开启AOF appendonly yes # AOF文件名 appendfilename "appendonly.aof" # RDB文件和AOF文件所在目录 dir /data # fsync持久化策略 appendfsync everysec # AOF重写期间是否禁止fsync;如果开启该选项,可以减轻文件重写时CPU和硬盘的负载(尤其是硬盘),但是可能会丢失AOF重写期间的数据;需要在负载和安全性之间进行平衡 no-appendfsync-on-rewrite no
文件重写触发条件之一 百分比
auto-aof-rewrite-percentage 100
文件重写触发提交之一 大小
auto-aof-rewrite-min-size 64mb
如果AOF文件结尾损坏,Redis启动时是否仍载入AOF文件
aof-load-truncated yes
## RDB与AOF的区别
| 持久化方式 | RDB | AOF |
| ------------ | ------------------ | ------------------ |
| 占用存储空间 | 小(数据级:压缩) | 大(指令集:重写) |
| 存储速度 | 慢 | 快 |
| 恢复速度 | 快 | 慢 |
| 数据安全性 | 会丢失数据 | 依据策略决定 |
| 资源消耗 | 高/重量级 | 低/轻量级 |
| 启用优先级 | 低 | 高 |
### RDB与AOF之间的选择
* 对数据非常敏感,建议使用默认的AOF持久化
* AOF持久化策略使用everysecond,每秒钟fsync一次,该策略redis仍可以保持很好的处理性能,当出现问题是,最多丢失0-1秒内的数据
* 注意:由于AOF文件存储体积较大,且恢复速度较慢
* 数据呈现阶段有效性,件以使用RDB持久化方案
* 数据可以良好的做到阶段内无丢失(开发或运维手工维护),且恢复速度较快,阶段点数据恢复通常采用RDB方案
* 注意:利用RDB实现紧凑的数据持久化会使Redis性能降低
* 综合对比
* RDB与AOF的选择实际上是在做一种权衡,每种都有利有弊
* 如不能承受数分钟以内的数据丢失,对业务数据非常敏感,选用AOF
* 如能承受,且追求大数据的恢复速度,选用RDB
* 灾难恢复选用RDB
* 双保险策略,同时开启RDB和AOF,重启后,redis优先使用AOF来恢复数据,降低数据丢失的量