Redis的 RDB 和 AOF 持久化机制

Redis的持久化方式

Redis作为高效的缓存件,它的数据存放在内存中,如果没有配置持久化,那么数据会在重启后丢失,因此如果不是仅用Redis做缓存的话,需要开启Redis的持久化功能,将数据保存到磁盘上,当Redis重启后,可以从磁盘中恢复数据。

Redis提供两种数据持久化的方式

  • 快照(snapshotting,RDB)持久化:默认支持,原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化。
  • AOF(只追加文件【append-only file,AOF】)持久化:将以日志形式,记录服务器所处理的每一个操作指令,在Redis服务器启动之初,会读取该文件,重新构建数据库,保证启动后数据的完整性。

RDB

快照(snapshotting,RDB)持久化,是指在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,采用二进制压缩存储。

保存数据

  • 指令(前台保存):save //阻塞 立即保存
  • 指令(fork一个子进程后台保存):bgsave //不立即执行

RDB的配置项

快照持久化是Redis默认采用的持久化方式,在redis.conf配置文件中默认有此下配置:

#在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发BGSAVE命令创建快照。
save 900 1 
save 300 10 
save 60 10000 
#本地数据库存放目录,默认当前
dir ./ 
#本地数据库文件名,默认:dump.rdb
dbfilename dump.rdb  
#默认开启数据压缩
rdbcompression yes  
#是否开启格式检查,默认no
rdbchecksum no 
#后台用bgsave执行操作
save second changes

根据配置,快照将被写入dbfilename选项指定的文件里面,并存储在dir选项指定的路径上面。如果在新的快照文件创建完毕之前,Redis、系统或者硬件这三者中的任意一个崩溃了,那么Redis将丢失最近一次创建快照写入的所有数据。


创建快照的方法有如下几种:

  • BGSAVE命令: 客户端向Redis发送 BGSAVE命令 来创建一个快照。对于支持BGSAVE命令的平台来说(基本上所有平台支持,除了Windows平台),Redis会调用fork来创建一个子进程,然后子进程负责将快照写入硬盘,而父进程则继续处理命令请求。
  • SAVE命令: 客户端还可以向Redis发送 SAVE命令 来创建一个快照,接到SAVE命令的Redis服务器在快照创建完毕之前不会再响应任何其他命令。SAVE命令不常用,我们通常只会在没有足够内存去执行BGSAVE命令的情况下,又或者即使等待持久化操作执行完毕也无所谓的情况下,才会使用这个命令。
  • SAVE选项: 如果用户设置了save选项(一般会默认设置),比如 save 60 10000,那么从Redis最近一次创建快照之后开始算起,当“60秒之内有10000次写入”这个条件被满足时,Redis就会自动触发BGSAVE命令。
  • SHUTDOWN命令: 当Redis通过SHUTDOWN命令接收到关闭服务器的请求时,或者接收到标准TERM信号时,会执行一个SAVE命令,阻塞所有客户端,不再执行客户端发送的任何命令,并在SAVE命令执行完毕之后关闭服务器。
  • 一个Redis服务器连接到另一个Redis服务器: 当一个Redis服务器连接到另一个Redis服务器,并向对方发送SYNC命令来开始一次复制操作的时候,如果主服务器目前没有执行BGSAVE操作,或者主服务器并非刚刚执行完BGSAVE操作,那么主服务器就会执行BGSAVE命令

RDB持久化的优点

  • RDB存储的是Redis在某个时间点的数据快照,非常适用于数据备份全量复制等场景
  • 对于灾难恢复而言,RDB是非常不错的选择。因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上。
  • 性能最大化。对于Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了。
  • RDB是一个紧凑压缩的二进制文件,存储效率高
  • RDB恢复数据速度比AOF快

RDB存储的弊端

  • 存储数据量较大的时候,效率较低,基于快照思想,每次读写都是全部数据,当数据量巨大的时候效率非常低
  • 大数据量下IO性能较低
  • 基于fork创建子进程,产生额外内存消耗
  • 如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。

AOF

AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中命令,达到恢复数据的目的。与RDB相比可以简单描述为改记录数据为记录数据产生的过程
AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式

AOF优点

  • 该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3种同步策略,即每秒同步每修改同步不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。至于无同步,也就是由系统控制。
  • 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果我们本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据一致性的问题。
  • 如果日志过大,Redis可以自动启用rewrite机制 。即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性。
rewrite机制
AOF文件随着写命令的运行膨胀时,当文件大小触碰到临界时,rewrite会被运行。
rewrite会像replication一样,fork出一个子进程,创建一个临时文件,遍历数据库,将每个key、value对输出到临时文件。输出格式就是Redis的命令,但是为了减小文件大小,会将多个key、value对集合起来用一条命令表达。在rewrite期间的写操作会保存在内存的rewrite buffer中,rewrite成功后这些操作也会复制到临时文件中,在最后临时文件会代替AOF文件。

AOF配置项

与快照持久化相比,AOF持久化 的实时性更好。默认情况下Redis没有开启AOF(append only file)方式的持久化,需要通过appendonly参数开启

appendonly yes              #默认关闭,需要手动把no改为yes
appendfilename "appendonly.aof"     #本地数据库文件名,默认值为 appendonly.aof
dir ./                   #本地数据库存放目录,默认当前目录

AOF提供了三种更新日志的条件

appendfsync always     #每次有数据修改发生时都会写入AOF文件,这样会严重降低Redis的速度
appendfsync everysec   #每秒钟同步一次,显示地将多个写命令同步到硬盘
appendfsync no         #让操作系统决定何时进行同步
  • appendfsync always 可以实现将数据丢失减到最少,不过这种方式需要对硬盘进行大量的写入而且每次只写入一个命令,十分影响Redis的速度
  • 为了兼顾数据和写入性能,用户可以考虑 appendfsync everysec选项 ,让Redis每秒同步一次AOF文件,Redis性能几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操作的时候,Redis还会优雅的放慢自己的速度以便适应硬盘的最大写入速度。
  • appendfsync no 选项一般不推荐,这种方案会使Redis丢失不定量的数据而且如果用户的硬盘处理写入操作的速度不够的话,那么当缓冲区被等待写入的数据填满时,Redis的写入操作将被阻塞,这会导致Redis的请求速度变慢。

AOF重写规则

  • 进程内已超时的数据不再写入文件
  • 忽略无效指令,重写时使用进程内数据直接生成,这样新的AOF文件只保留最终数据的写入命令 如del key1、 hdel key2、srem key3、set key4 111、set key4 222等
  • 对同一数据的多条写命令合并为一条命令,如lpush list1 a、lpush list1 b、 lpush list1 c 可以转化为:lpush list1 a b c。 为防止数据量过大造成客户端缓冲区溢出,对list、set、hash、zset等类型,每条指令最多写入64个元素

AOF重写方式

  • 手动重写
    bgrewriteaof
  • 自动重写触发条件设置

    • auto-aof-rewrite-min-size 64mb //aof当前大小达到了当前设置的最小尺寸就重写
    • auto-aof-rewrite-percentage 100 //百分比
  • 自动重写触发对比参数

    • aof_current_size //aof当前size
    • aof_base_size //基础尺寸

添加新评论

评论列表