当前位置: 移动技术网 > IT编程>数据库>Redis > Redis的持久化方案详解

Redis的持久化方案详解

2020年06月23日  | 移动技术网IT编程  | 我要评论

redis支持rdb与aof两种持久化机制,持久化可以避免因进程异常退出或down机导致的数据丢失问题,在下次重启时能利用之前的持久化文件实现数据恢复。

rdb持久化

rdb持久化即通过创建快照(压缩的二进制文件)的方式进行持久化,保存某个时间点的全量数据。rdb持久化是redis默认的持久化方式。rdb持久化的触发包括手动触发与自动触发两种方式。

手动触发

  • save, 在命令行执行save命令,将以同步的方式创建rdb文件保存快照,会阻塞服务器的主进程,生产环境中不要用
  • bgsave, 在命令行执行bgsave命令,将通过fork一个子进程以异步的方式创建rdb文件保存快照,除了fork时有阻塞,子进程在创建rdb文件时,主进程可继续处理请求

自动触发

在redis.conf中配置 save m n 定时触发,如 save 900 1表示在900s内至少存在一次更新就触发
主从复制时,如果从节点执行全量复制操作,主节点自动执行bgsave生成rdb文件并发送给从节点
执行debug reload命令重新加载redis时
执行shutdown且没有开启aof持久化
redis.conf中rdb持久化配置

 # 只要满足下列条件之一,则会执行bgsave命令
save 900 1 # 在900s内存在至少一次写操作
save 300 10
save 60 10000
# 禁用rbd持久化,可在最后加 save ""

# 当备份进程出错时主进程是否停止写入操作
stop-writes-on-bgsave-error yes
# 是否压缩rdb文件 推荐no 相对于硬盘成本cpu资源更贵
rdbcompression no

aof持久化

aof(append-only-file)持久化即记录所有变更数据库状态的指令,以append的形式追加保存到aof文件中。在服务器下次启动时,就可以通过载入和执行aof文件中保存的命令,来还原服务器关闭前的数据库状态。

redis.conf中aof持久化配置如下

# 默认关闭aof,若要开启将no改为yes
appendonly no

# append文件的名字
appendfilename "appendonly.aof"

# 每隔一秒将缓存区内容写入文件 默认开启的写入方式
appendfsync everysec

# 当aof文件大小的增长率大于该配置项时自动开启重写(这里指超过原大小的100%)。
auto-aof-rewrite-percentage 100

# 当aof文件大小大于该配置项时自动开启重写
auto-aof-rewrite-min-size 64mb

aof持久化的实现包括3个步骤:

  • 命令追加:将命令追加到aof缓冲区
  • 文件写入:缓冲区内容写到aof文件
  • 文件保存:aof文件保存到磁盘

其中后两步的频率通过appendfsync来配置,appendfsync的选项包括

  • always, 每执行一个命令就保存一次,安全性最高,最多只丢失一个命令的数据,但是性能也最低(频繁的磁盘io)
  • everysec,每一秒保存一次,推荐使用,在安全性与性能之间折中,最多丢失一秒的数据
  • no, 依赖操作系统来执行(一般大概30s一次的样子),安全性最低,性能最高,丢失操作系统最后一次对aof文件触发save操作之后的数据

aof通过保存命令来持久化,随着时间的推移,aof文件会越来越大,redis通过aof文件重写来解决aof文件不断增大的问题(可以减少文件的磁盘占有量,加快数据恢复的速度),原理如下:

调用fork,创建一个子进程

子进程读取当前数据库的状态来“重写”一个新的aof文件(这里虽然叫“重写”,但实际并没有对旧文件进行任何读取,而是根据数据库的当前状态来形成指令)

主进程持续将新的变动同时写到aof重写缓冲区与原来的aof缓冲区中

主进程获取到子进程重写aof完成的信号,调用信号处理函数将aof重写缓冲区内容写入新的aof文件中,并对新文件进行重命名,原子地覆盖原有aof文件,完成新旧文件的替换

aof的重写也分为手动触发与自动触发

  • 手动触发: 直接调用bgrewriteaof命令
  • 自动触发: 根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机。其中auto-aof-rewrite-min-size表示运行aof重写时文件最小体积,默认为64mb。auto-aof-rewrite-percentage表示当前aof文件大小(aof_current_size)和上一次重写后aof文件大小(aof_base_size)的比值。自动触发时机为 aof_current_size > auto-aof-rewrite-min-size &&(aof_current_size - aof_base_size)/aof_base_size> = auto-aof-rewrite-percentage

rdb vs aof

rdb与aof两种方式各有优缺点。

  • rdb的优点:与aof相比,rdb文件相对较小,恢复数据比较快(原因见数据恢复部分)
  • rdb的缺点:服务器宕机,rbd方式会丢失掉上一次rdb持久化后的数据;使用bgsave fork子进程时会耗费内存。
  • aof的优点: aof只是追加文件,对服务器性能影响较小,速度比rdb快,消耗内存也少,同时可读性高。
  • aof的缺点:生成的文件相对较大,即使通过aof重写,仍然会比较大;恢复数据的速度比rdb慢。

数据库的恢复

服务器启动时,如果没有开启aof持久化功能,则会自动载入rdb文件,期间会阻塞主进程。如果开启了aof持久化功能,服务器则会优先使用aof文件来还原数据库状态,因为aof文件的更新频率通常比rdb文件的更新频率高,保存的数据更完整。

redis数据库恢复的处理流程如下,

在数据恢复方面,rdb的启动时间会更短,原因有两个:

rdb 文件中每一条数据只有一条记录,不会像aof日志那样可能有一条数据的多次操作记录。所以每条数据只需要写一次就行了,文件相对较小。

rdb 文件的存储格式和redis数据在内存中的编码格式是一致的,不需要再进行数据编码工作,所以在cpu消耗上要远小于aof日志的加载。

但是在进行rdb持久化时,fork出来进行dump操作的子进程会占用与父进程一样的内存,采用的copy-on-write机制,对性能的影响和内存的消耗都是比较大的。比如16g内存,redis已经使用了10g,这时save的话会再生成10g,变成20g,大于系统的16g。这时候会发生交换,要是虚拟内存不够则会崩溃,导致数据丢失。所以在用redis的时候一定对系统内存做好容量规划。

rdb、aof混合持久化

redis从4.0版开始支持rdb与aof的混合持久化方案。首先由rdb定期完成内存快照的备份,然后再由aof完成两次rdb之间的数据备份,由这两部分共同构成持久化文件。该方案的优点是充分利用了rdb加载快、备份文件小及aof尽可能不丢数据的特性。缺点是兼容性差,一旦开启了混合持久化,在4.0之前的版本都不识别该持久化文件,同时由于前部分是rdb格式,阅读性较低。

开启混合持久化

aof-use-rdb-preamble yes

数据恢复加载过程就是先按照rdb进行加载,然后把aof命令追加写入。

持久化方案的建议

如果redis只是用来做缓存服务器,比如数据库查询数据后缓存,那可以不用考虑持久化,因为缓存服务失效还能再从数据库获取恢复。

如果你要想提供很高的数据保障性,那么建议你同时使用两种持久化方式。如果你可以接受灾难带来的几分钟的数据丢失,那么可以仅使用rdb。

通常的设计思路是利用主从复制机制来弥补持久化时性能上的影响。即master上rdb、aof都不做,保证master的读写性能,而slave上则同时开启rdb和aof(或4.0以上版本的混合持久化方式)来进行持久化,保证数据的安全性。

到此这篇关于redis的持久化方案详解的文章就介绍到这了,更多相关redis的持久化方案内容请搜索移动技术网以前的文章或继续浏览下面的相关文章希望大家以后多多支持移动技术网!

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网