[沫忘录]Redis 持久化
Redis的数据主要储存于内存,如果不将这些数据以某种方式持久化到磁盘上做备份,则很有可以在各种突发情况而导致的Redis崩溃中丢失数据。
持久化主要有以下四种方式:
RDB:数据快照保存。
AOF:保存写日志到磁盘上。
No persistence:不做任何持久化处理,纯缓存模式。
RDB + AOF:采用RDB和AOF混合的方式,对数据进行可持久化处理。
RDB(redis database)
RDB 持久性以指定时间间隔执行数据集的时间点快照,快照通常储存在RDB文件(dump.rdb)中。
redis[7].conf参数设置
#在配置文件中SNAPSHOTTING模块下
#设置second秒后修改达change次后,保存快照
save <second> <change>
默认配置:
Redis6.0.16以下
save 900 1
save 300 10
save 60 10000Redis6.2以及Redis-7.0.0
save 3600 1
save 300 100
save 60 10000
#设置dump文件的保存路径,默认./
dir /myredis/dumpfiles #示例路径(该路径文件已存在)
#设置dump文件名,默认 dump.rdb
dbfilename dump6379.rdb #当有多台redis服务器,在dump后加端口号方便区分
自定义的修改路径可以进入redis里用CONFIG GET dir获取目录
当然,CONFIG GET也可以获取各种配置文件中的参数。
恢复redis数据
执行flushall/flushdb命令会刷新dump.rdb文件成空文件。
shutdown会直接保存当前数据快照。
在一般崩溃时,重启就会从dump.rdb文件读取数据。
而对应执行清空命令时,则需要使用事前拷贝的dump.rdb的副本来替换当前正在使用的rdb文件。(物理恢复)
因此不能将备份文件dump.rdb和生产redis服务器放同一台机器,必须分开各自储存以防生产机物理损害后备份文件也损坏了。
手动触发
redis提供了两个命令来生成RDB文件
#阻塞保存RDB文件,生产禁止使用,严重影响效率
SAVE
#创建子进程保存RDB文件
BGSAVE
#获取最后一次成功保存快照的时间戳
LASTSAVE
#可以在命令行上使用以下命令转换成自然时间
date -d @时间戳
优点
- 适合大规模的数据备份
- 按照业务定时备份
- 对数据的完整性和一致性要求不高
- RDB文件在内存的加载速度比AOF快得多(AOF需要每条指令都执行,一步步恢复数据)
劣势
- 备份的时间粒度太大,如果崩溃,丢失最后一次备份之后的数据时,数据偏多
- RDB会经常创建子进程进行数据备份,如果数据量过大,子进程过多,会导致内存占用过多的同时服务请求产生瞬间延迟。
修复rdb文件
rdb文件内如果出现乱码或违规数据会导致无法启动redis。
此时需要使用指令进行数据修复。
#修复指令
redis-check-rdb /myredis/dumpfiles/dump.rdb #即rdb文件的路径
禁用快照
#短期禁用
redis_cli config set save ""
#永久禁用,在redis.config文件设置
save ""
AOF(append only file)
AOF指以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来,追加在日志文件中。
当Redis启动时,会读取该文件重新构建数据。
AOF默认关闭,当需要使用AOF时,需要在配置文件中设置以下命令
appendonly yes
当写命令到到达Redis Server后,并不会直接写入AOF文件,而是将其先写入AOF缓存区中保存,然后再根据三种写回策略写入AOF文件,类似于MySQL内存中的change buffer缓冲区写入到磁盘上的systemtable系统表空间中。
当AOF文件无法写入(或写入量到达一定峰值)后,会触发重写机制。Redis服务器会根据当前数据库的数据状态,在重写缓冲区中重构AOF文件,然后将新文件覆盖到旧文件上。
三种写回策略
- Always 每个写回命令执行完后立刻同步地将日志写回磁盘。
- everysec 每秒写回,每个命令执行完后,先将日志写到AOF文件的内存缓冲区,然后每隔1秒把缓冲区的内容写入到磁盘。
- no 每个写命令存放在AOF缓冲区,然后由操作系统决定何时写回磁盘空间(如果宕机,丢失数据过多)。
配置参数
appendfsync every sec
版本迭代导致的AOF文件目录变化
-
redis 6及之前,dump.rdb和appendonly.aof文件都储存在同一个目录(RDB目录)下。
-
redis 7及之后,Redis在RDB目录下新建了appendonlydir文件夹用以存放aof文件。
#配置参数 appenddirname "appendonlydir"
版本迭代导致的AOF文件名变化
-
redis 6及之前,日志信息统一存放在一个AOF文件中。
#配置参数 appendfilename "appendonly.aof"
-
redis 7及之后,在相同的配置参数下,AOF文件被拆分成多个AOF文件:
- BASE(如appendonly.aof.1.base.rdb):表示基础AOF, 一般由子进程重写产生,该文件至多一个。
- INCR(如appendonly.aof.n.incr.aof):表示增量AOF,一般在AOFRW(即AOF文件重写)开始执行时被创建,该文件存在多个。
- HISTORY:表示历史AOF,每当AOFRW成功后,BASE和INCR文件都将变成HISTORY文件,该文件由Redis自动删除。(该文件不可见但存在)
- 为了方便管理这些文件,引入了一个manifest(清单)文件来跟踪管理这些AOF文件。
Redis数据恢复
物理恢复同RDB文件一样,需要手动拷贝,手动覆盖。
异常恢复也需要使用指令进行文件恢复。
redis-check-aof --fix 待修复的.incr.aof文件
#这个是日常工作记录数据的最主要文件,一般对该文件进行修复操作。
优势
- AOF在非纯缓存模式下,最多丢失1秒以内的数据。三种写回策略能够给予用户对性能和数据一致性之间权衡的可操作性。
- AOF日志是一个仅附加日志,因此不会出现磁盘寻道问题,也不会在断电时出现文件损坏问题。即使因某种原因导致最新的日志写入不全,也能通过redis-check-aof进行文件修复。
- 当AOF文件过大时,重写机制也能极大的缩减文件体积,避免了因文件溢出导致的数据丢失。
- AOF文件可读性强且易导出。而且AOF文件能够在某种程度上提供数据回滚机制:当不小心使用
FLUSHALL
指令清除了所有数据,只要在此期间没有执行日志重写,那么仍可以通过shutdown
停止服务器,删除AOF文件的最新指令来恢复数据。
劣势
- AOF文件通常比相同数据集的等效RDB文件要大。
- AOF文件的写入频次过高,磁盘IO频繁,相比于RDB,在巨大负载的情况下,延迟可能过高。
- 由于AOF的恢复策略,导致AOF的数据恢复要慢于RDB。
重写机制
自动触发
配置参数
auto-aof-rewrite-percentage 100 #根据上次重写文件,文件大小增加的百分比幅度
auto-aof-rewrite-min-size 64mb #触发重写的文件大小
#两者同时满足才会触发重写
正如上面提到的,AOF文件重写是根据数据库当前的数据状态,因此对同一key的写操作只会保留最新的一次。
手动触发
使用指令**BGREWRITEAOF
**直接触发重写。
当"重写子进程"完成重写工作后,它会给父进程发一个信号,父进程收到信号后会将内存中缓存的写指令追加到新的AOF文件中,然后用新文件覆盖旧文件。
#是否允许在重写时继续追加新的AOF日志的配置参数
no-appendfsync-on-rewrite no/yes
RDB-AOF混合持久化
RDB和AOF两种模式能够共存。但AOF的优先级比RDB高,当有AOF时,优先由其来进行数据恢复。
#开启混合模式的配置参数
aof-use-rdb-preamble no/yes
在混合模式开启后,RDB模式做全量持久化,AOF模式做增量持久化。当触发重写时,RDB将生成最新数据的快照。
纯缓存模式
即同时关闭RDB和AOF的模式,适用于高性能服务器。
即使禁用了RDB和AOF,我们仍可以手动触发两种模式的文件的生成。