Redis 持久化

Redis提供了两种持久化方式:

  • RDB (Redis DataBase)
    在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)

  • AOP(Append Only File)
    记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。

Redis 还可以同时使用 AOF 持久化和 RDB 持久化。 在这种情况下, 当 Redis 重启时, 它会优先使用 AOF 文件来还原数据集, 因为 AOF 文件保存的数据集通常比 RDB 文件所保存的数据集更完整。

RDB

Redis 会单独的创建(fork) 一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程结束了,再用这个临时文件替换上次持久化还的文件。
整个过程中,主进程是不进行任何 IO 操作,这就确保了极高的性能,如果需要进行大规模的数据恢复,且对于数据恢复的完整性不是非常敏感,那 RDB 方法要比 AOF 方式更加的高效。
RDB 的缺点是最后一次持久化后的数据可能丢失。若当前的进程的数据量庞大,那么 fork 之后数据量*2,此时就会造成服务器压力大,运行性能降低。
fork 的作用是复制一个与当前进程一样的进程,新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。之所以不使用线程而选择fork子进程,是利用了fork复制进程资源的特性,将redis当前状态拷贝一份,再持久化到文件中。而线程的做法就会破坏redis的单线程读写模型,造成对数据的竞争。

执行:

  • 开启配置:

    save 900 1     
    #900秒内如果超过1个key被修改,则发起快照保存
    
    save 300 10    
    #300秒内容如超过10个key被修改,则发起快照保存
    
    save 60 10000
    #60秒内容如超过10000个key被修改,则发起快照保存
    
  • 命令执行:
    SAVE 直接调用rdbSave,阻塞Redis主进程看,直到保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任何请求。
    BGSAVE 则fork 出一个子进程,子进程负责调用rdbSave ,并在保存完成之后向主进程发送信号,通知保存已完成。因为rdbSave 在子进程被调用,所以Redis 服务器在BGSAVE 执行期间仍然可以继续处理客户端的请求。

AOP

AOF 则以协议文本的方式,将所有对数据库进行过写入的命令(及其参数)记录到AOF文件,以此达到记录数据库状态的目的。AOF文件其实可以认为是Redis写操作的日志记录文件。

开启配置:

appendonly yes              //启用aof持久化方式
# appendfsync always      //每次收到写命令就立即强制写入磁盘,最慢的,但是保证完全的持久化,不推荐使用
appendfsync everysec     //每秒钟强制写入磁盘一次,在性能和持久化方面做了很好的折中,推荐
# appendfsync no    //完全依赖os,性能最好,持久化没保证

Rewrite
AOF 采用文件追加方式,文件会越来越来大。为避免出现此种情况,新增了重写机制:当aof 文件的大小超过所设定的阈值时,redis 就会自动 aof 文件的内容压缩,值保留可以恢复数据的最小指令集,可以使用命令bgrewirteaof。
重写原理:aof 文件持续增长而大时,会fork出一条新进程来将文件重写(也就是先写临时文件最后再rename)。重写aof文件时并没有读取原来的文件,而是遍历新进程的内存中的数据,将其作为写命令追加到文件,这点和快照有点类似。
触发机制:redis 会记录上次重写的 aof 的大小,默认的配置当 aof 文件大小上次 rewrite 后大小的一倍且文件大于 64M 触发

no-appendfsync-on-rewrite no
# 重写时是否可以运用 Appendfsync 用默认no即可,保证数据安全
auto-aof-rewrite-percentage 100
# 重写触发的倍数
auto-aof-rewrite-min-size 64mb
# 设置基准值大小

优势
AOP的优势在于使得Redis变得非常可靠:你可以设置不同的 fsync 策略,比如无 fsync ,每秒钟一次 fsync ,或者每次执行写入命令时 fsync 。 AOF 的默认策略为每秒钟 fsync 一次,在这种配置下,Redis 仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据( fsync 会在后台线程执行,所以主线程可以继续努力地处理命令请求)

AOF 文件是一个只进行追加操作的日志文件(append only log), 因此对 AOF 文件的写入不需要进行 seek , 即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等等), redis-check-aof 工具也可以轻易地修复这种问题。

Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写: 重写后的新 AOF 文件包含了恢复当前数据集所需的最小命令集合。 整个重写操作是绝对安全的,因为 Redis 在创建新 AOF 文件的过程中,会继续将命令追加到现有的 AOF 文件里面,即使重写过程中发生停机,现有的 AOF 文件也不会丢失。 而一旦新 AOF 文件创建完毕,Redis 就会从旧 AOF 文件切换到新 AOF 文件,并开始对新 AOF 文件进行追加操作。

AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。 导出(export) AOF 文件也非常简单: 举个例子, 如果你不小心执行了 FLUSHALL 命令, 但只要 AOF 文件未被重写, 那么只要停止服务器, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重启 Redis , 就可以将数据集恢复到 FLUSHALL 执行之前的状态。

缺点

对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。

根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入载入时,RDB 可以提供更有保证的最大延迟时间(latency)。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章