Redis持久化
持久化的原理就是将内存中的数据写入硬盘进行保存,持久化的原因就是需要保证出现意外情况下,不出现缓存全部消失导致数据库负载过高崩溃的情况。
Redis的持久化实现
Redis的持久化主要是通过RDB(Redis Database)和AOF(Append Only File)实现的,当然也可以选择不进行持久化或同时使用RDB+AOF
- RDB:将快照存储到数据库中,从数据库中恢复缓存
- AOF:把执行的命令存储下来,重新执行一次以恢复数据
RDB(Redis Database)
在指定的时间间隔之内,执行数据集的保存快照,写入磁盘以保证数据安全;这个快照文件的名称是RDB文件(dump.drb)
在保存快照是使用的是全量快照,也就是把内存中全部的数据都保存到磁盘中,恢复时再将数据读入到内存中;
RDB案例
-
RDB保存策略
-
在Redis6.0,可以在配置文件的SNAPSHOT模块下配置save参数,从而触发RDB持久化条件,save m n 表示在m秒内数据发生了n次变化,就会触发一次持久化操作,保存一份RDB文件;每隔900秒有1个key发生变化就保存一次,每隔300秒有10个key发生变化就保存,每个60秒有10000个key变化就报错;保存频率较高
-
从Redis7开始,RDB的保存时间间隔发生了变化;3600秒内有一个修改,300秒内有60次修改,60秒内有10000次修改就保存一次;保存频率降低了一些
Unless specified otherwise, by default Redis will save the DB: # * After 3600 seconds (an hour) if at least 1 change was performed # * After 300 seconds (5 minutes) if at least 100 changes were performed # * After 60 seconds if at least 10000 changes were performed # # You can set these explicitly by uncommenting the following line. # # save 3600 1 300 100 60 10000
-
-
RDB设置
-
设置RDB保存策略
在配置文件中自定义 save m n,m时间间隔,n为修改触发次数;这个检查是每m秒执行一次的,在每个时间片内达到n次修改就会保存,与数据修改的时间无关。
-
设置RDB文件生成路径
设置dir /myrdb 自定义文件夹作为自己保存备份文件的路径,这个路径文件夹不能为空,必须自己建立
-
设置rdb文件的名称,主要是为了在多个redis运行时了解是哪个redis的文件,一般设置为dump+端口号
在配置文件中设置 dbfilename dump6379.rdb 作为默认的rdb文件名称
-
修改完成后,重启redis;可以通过redis-cli使用 config get xxx 获取配置的参数,可以依次检查参数是否正确
-
-
触发备份
- 自动触发
- 在redis中存在超过触发阈值的数据,可以使用flushdb触发一次持久化操作,可以看到文件生成
- 在指定时间间隔内触发一定数量的操作
- 如果使用shutdown或者flushdb等指令时,会立刻生成一个rdb文件;flushdb产生的rdb是空文件
- 手动触发
- 使用 Save 命令 和 BGSave命令,会使用fork产生一个子进程,开始完成持久化的操作
- 但一般只允许使用BGSave,因为Save会阻塞Redis主线程,使得其停止任何服务一段时间去等待备份完成
- LASTSAVE 可以获取最后一次成功执行快照的时间,这是一个毫秒时间戳,需要在linux中输入 date -d @时间戳 转换成正常的时间显示
- 自动触发
-
恢复备份
- 将备份文件移动到redis的rdb的保存目录并重新启动即可;使用flushdb清空redis(移除最新生成的rdb文件),再启动redis后就会成功恢复
- 如果产生了正确数据的dump.rdb,一定要实现备份和分机隔离,不能放在和redis相同的数据
RDB特点
- 优点
- 适合大规模的数据恢复和云备份
- 是单文件且按按照业务定时备份的
- 对数据的完整性和一致性要求不高
- RDB文件的加载比AOF快很多
- 缺点
- 在一定的时间间隔做一次备份,如果redis在未保存时出现意外关闭,可能会丢失最新快照保存后新加入的数据
- 内存数据依赖全量同步,如果数据量太大可能导致I/O影响服务器性能
- RDB依赖于fork,如果数据集过大,在fork时需要克隆一份数据可能导致内存和CPU的高占用
数据丢失案例
在上一次完成了持久化操作,之后又修改了Redis,但未触发自动保存或手动保存时出现了意外关闭,上一次持久化之后的修改都会丢失
RDB文件损坏
如果rdb文件损坏,可以运行rdb修复脚本 redis-check-rdb dump.rdb 来尽可能修复保存的数据
RDB快照触发总结
- 配置文件中设定的自动触发,在m秒内修改n次
- 手动 save/bgsave,使用子进程保存
- 执行flushall/flushdb,但保存的文件是空的
- 执行shutdown且没有设置AOF
- 主从复制时,主节点自动触发
RDB快照关闭
- 只生效一次时,执行 redis-cli config set save “”,即将save配置给停用,这种配置方法仅一次启动有效
- 彻底快照禁用 需要在配置文件中设置 save “”
RDB优化配置
在SNAPSHOTTING模块中,可以配置一些其他的参数
- stop-writes-on-bgsave-error yes :默认是yes,即如果bgsave发生错误时就拒绝写请求
- rdbcompression yes :默认为yes,即使用LZF算法压缩rdb文件,如果不需要消耗CPU压缩可以设置为no
- rdbchecksum yes:默认为yes,存储快照后让Redis使用CRC64算法进行数据校验,但是大概会增加10%的性能消耗
- reb-del-sync-files no:默认为no,在没有启用持久化的情况下是否需要删掉复制中使用的RDB文件
AOF(Append Only File)
以日志的形式记录每个写操作,但不记录读操作,只允许追加但不允许改写文件。在redis启动时只需要把该文件再操作一次即可恢复数据。
为了避免RDB出现的数据丢失,可以采用AOF来作为补充;每次写操作都会写入AOF文件,并通过重读AOF文件来获取全部数据
默认情况下,Redis不会开启AOF,需要在配置文件中设置 appendonly yes ,其保存的文件为appendonly.aof
AOF工作流程
- Client发送命令给Redis
- 这些需要记录命令会先到达AOF缓冲区,到达一定数量再触发写入
- AOF缓存会根据AOF缓冲区同步文件的三种写回策略将命令写入磁盘的AOF文件
- 为了避免AOF内容增加和文件膨胀,会触发AOF重写(根据规则合并一些命令),从而压缩AOF文件
- 在Redis重启时,再次读取AOF文件并执行操作以恢复数据
AOF写回策略
-
Always
每个写命令到达后,立刻写入到磁盘,但是IO过于频繁
-
everysec
默认的写回策略;先把命令写入AOF缓冲区,每隔1秒写入磁盘一次即可
-
no
操作系统控制的写回,每个写命令执行完了,只是把操作到AOF缓冲区,操作系统决定其写回磁盘的时间;可能导致数据丢失,IO太少
AOF案例
- 配置文件 在配置文件中的 appendonly 改为 yes
- 使用默认的写回策略 appendsync everysec,不用改动
- AOF文件保存路径
- Redis6:和RDB文件一样,使用 dir 配置目录来存储aof文件
- Redis7:需要设置appenddirname “appendonlydir”来配置aof文件存储路径,这会导致在dir配置的目录后增加一个子目录来存储aof文件
- AOF保存名称
- Redis6:只要一个 appendfilename “appendonly.aof”来配置名称
- Redis7:AOF变成了Mutilpart AOF,由3个文件存储,仍然使用appendfilename “appendonly.aof”配置名称
- BASE:基本文件,一般是子进程重写产生,最多只有一个
- INCR:增量文件,存放写操作命令,在AOF重写时进行,可能存在多个
- HISTORY:历史AOF,由base和incr变化而来,会被Redis自动删除
- MANIFEST:为了管理这些文件,引入了清单文件来管理这些AOF
AOF异常恢复
在写入AOF文件的时候,可能存在异常导致写入中断,使得AOF文件不完整或写入乱码;此时再次尝试启动Redis服务器会导致报错,需要恢复正确的数据在AOF文件中才能运行。
需要执行 redis-check-aof --fix appendonly.aof.1.incr.aof 指令来修复增量文件
AOF特点
- 优点
- AOF拥有三种持久化策略;默认每秒的fsync性能很好,而且最多丢失1秒的数据
- AOF是一个仅附加日志,所以不会出现寻道问题,也不会在断电时出现损坏;即使文件写入损坏,也可以修复其末尾错误的部分
- 当AOF过大时,可以自动重写AOF,并且是完全安全的
- AOF保存了全部修改相关指令,在日志没有覆写之前,就可以恢复数据
- 缺点
- AOF文件通常比相同数据下的RDB大,恢复速度慢于RDB
- 运行效率较RDB低,每秒同步则效率较高,不同步则和RDB相同
AOF重写机制
AOF随着命令越来越多,文件也会增大,所以需要减小。为了解决这个问题,Redis增加了重写机制,当AOF文件超过设定的最大大小后或者手动执行了 bgrewriteaof 指令后,Redis就会开始压缩AOF文件内容,只保留可以恢复数据的最小指令集。
- 配置文件中 auto-aof-rewrite-percentage 和 auto-aof-rewrite-min-size指定了触发重写的百分比和触发的最小文件大小;百分比是指和上次执行aof增量文件大小相比;这两个条件必须同时满足;默认为100%和64mb
- 只保留可以恢复数据的最小指令集,即只记录某个键最后一次修改的操作,即可恢复到最后的数据状态
- appendonly.aof.x.base.aof 用来在每次触发重写后的最小指令集;而incr文件用来在未触发重写时记录指令,但触发重写后增量文件被清空,只记录base文件中最小指令集执行之后的指令;而且每次执行重写,base和incr文件的编号会加1
- 重写原理
- 重写开始前,Redis会创建一个重写子进程,读取内存中的Redis数据库,重写一份AOF文件。
- 与此同时主进程仍然接收写指令并累计到内存缓冲区中,一边继续写入到增量文件中,这样保证了重写意外时也能正常运行。
- 重写子进程完成重写后,父进程就可以将内存中的写指令写道新的aof文件中。
- 之后,Redis就可以用新的AOF代替之前的aof文件,之后的操作就写入到新文件中。
- 重写aof文件的操作,没有读取旧的aof文件,而是将这个内存数据库的内容用命令的方式重写了一次,和快照类似。
AOF优化配置
在APPEND ONLY MODE中的配置项
- appendonly 是否开启aof yes/no
- appendfilename aof文件名称
- appendsync 同步方式 everysec/always/no
- no-append-on-rewrite 重写期间是否同步 no/yes
- auto-aof-rewrite-percenatge 重写触发百分比 100/90/…
- auto aof-rewrite-min-size 重写触发最小文件阈值 64mb/…
RDB + AOF 混和持久化
这两种方式可以混和使用,如果同时开启则会优先加载AOF;
数据恢复加载流程
- 如果开启AOF,直接恢复AOF文件
- 如果不存在AOF,则查看是否存在RDB,如果存在在加载RDB
如何选择
通常情况下,AOF比RDB保存的数据更完整,所以这也是Redis默认的方式;
但AOF一直在变化,不好备份,所以可以留着RDB做多机备份
如何同时开启
在配置选项中 aof-use-rdb=preamble 设置开启,使用RDB做全量,而AOF做增量;此时恢复数据时,RDB先恢复全量数据,而AOF混写恢复增量数据,这样即保证了数据完整,也提高了恢复数据的性能;
纯缓存模式
同时关闭RDB和AOF,系统性能会更高;
- 使用 save “” 可以关闭rdb,但save和bgsave仍然有效
- appendonly no 可以关闭aof,但bgrewriteaof仍然可用
Redis的持久化通过RDB(RedisDatabase)和AOF(AppendOnlyFile)实现,RDB是全量快照,AOF记录写操作日志。RDB适合大规模恢复,但可能丢失部分数据,AOF则能保证更完整数据,但文件较大。AOF重写用于减小文件大小,避免文件过度增长。两者可混合使用,AOF优先级高于RDB。

917

被折叠的 条评论
为什么被折叠?



