Redis持久化

5 篇文章 0 订阅
2 篇文章 0 订阅

Redis持久化

概述

Redis的高性能是由于其将所有数据都存储在了内存中,为了使Redis在重启之后仍能保存数据不丢失,需要将数据从内存中同步到硬盘中,这一过程就是持久化。

Redis支持两种方式的持久化,一种是RDB方式,一种是AOF方式。可以单独使用其中一种或两种结合使用。

  1. RDB持久化(默认支持,无需配置):该机制是指在指定的时间间隔内将内存中的数据集快照写入磁盘。
  2. AOF持久化:该机制将以日志的形式记录服务器所处理的每一个写操作,在Redis服务器启动之初会读取该文件来重新构建数据库,以保证启动后数据库中的数据是完整的。
  3. 无持久化:我们可以通过配置的方式禁用Redis服务器的持久化功能,这样我们就可以将Redis视为一个功能加强版的memcached了。
  4. redis可以同时使用RDBAOF
  5. 由于Redis的数据都存放在内存中,如果没有配置持久化,redis重启后数据就全丢失了,于是需要开启redis的持久化功能,将数据保存到磁盘上,当redis重启后,可以从磁盘中恢复数据。redis提供两种方式进行持久化,一种是RDB持久化(原理是将Redis在内存中的数据库记录定时dump到磁盘上的RDB持久化),另外一种是AOF持久化(原理是将Redis的操作日志以追加的方式写入文件)。

RDB

RDB持久化是把当前进程数据生成快照保存到硬盘的过程,触发RDB持久化过程分为手动触发自动触发

  • 保存:RDB文件保存在dir配置指定的目录下,文件名通过dbfilename配置指定。可以通过执行config set dir {newDir}config set dbfilename {newFileName}运行期动态执行,当下次运行时RDB文件会保存到新目录。
  • 压缩:Redis默认采用LZF算法对生成的RDB文件做压缩处理,压缩后的文件远远小于内存大小,默认开启,可以通过参数config set rdbcompression {yes | no}动态修改。
  • 校验: 如果Redis加载损坏的RDB文件时拒绝启动,并打印如下日志:
    • Short read or OOM loading DB. Unrecoverable error, aborting now.

这时可以使用Redis提供的redis-check-dump工具检测RDB文件并获取对应的错误报告。

触发机制

手动触发分别对应savebgsave命令。

  • save命令:阻塞当前Redis服务器,直到RDB过程完成为止,对于内存比较大的实例会造成长时间阻塞,先上环境不建议使用。运行save命令对应Redis日志如下:DB saved on disk
  • bgsave命令:Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一段时间很短。运行bgsave名字对应的Redis日志如下:
Background saving started by pid 3152
DB saved on disk
RDB: 0MB of memory userd by copy-on-write
Background saving terminated with success
  • bgsave命令是针对save阻塞问题做的优化。因此Redis内部所有涉及到RDB操作都采用bgsave的方式,而save命令可以废弃。

    Redis内部还存在自动触发RDB的持久化机制,例如一下场景:

  1. 使用save相关配置,如save m n表示m秒之内数据集存在n次修改时,自动触发bgsave
  2. 如果从节点执行全量复制操作,主节点自动执行bgsave生成RDB文件并发送给从节点。
  3. 执行debug reload命令重新加载Redis时,也会自动触发save操作。
  4. 默认情况下执行shutdown命令时,如果没有开启AOF持久化功能则自动执行bgsave

bgsave 命令执行流程如下:
在这里插入图片描述

  1. 执行bgsave命令,Redis父进程判断当前是否存在正在执行的子进程,例如RDB/AOF子进程,如果存在bgsave命令直接返回。
  2. 父进程执行fork操作创建子进程,fork操作过程中父进程会阻塞,通过info stats命令查看latest_fork_usec选项,可以获取最近一个fork以操作的耗时,单位为微秒。
  3. 父进程仍fork完成后,bgsave命令返回Background saving started信息并不再阻塞父进程,可以继续响应其他命令。
  4. 子进程创建RDB文件,根据父进程内存生成临时快照文件,完成后对原有文件进行原子替换。执行lastsave命令可以获取最后一次生成尺RDB的时间,对应info统计的rdb_last_save_time选项。
  5. 进程发送信号给父进程以示完成,父进程更新统计信息,具体见info Persistence下的rdb_*相关选项。

优势

  • RDB是一个紧凑压缩的二进制文件,代表Redis在某一个时间点上的数据快照。非常适合用于备份,全量复制等场景。比如每6小时执行bgsave备份,并把RDB文件拷贝到远程机器或者文件系统中(如hdfs),用于灾难恢复。

Redis加载RDB恢复数据远远快于AOF方式。

  1. 一旦采用该方式,那么你的整个Redis数据库将只包含一个文件,这对于文件备份而言是非常完美的。比如,你可能打算每个小时归档一次最近24小时的数据,同时还要每天归档一次最近30天的数据。通过这样的备份策略,一旦系统出现灾难性故障,我们可以非常容易的进行恢复。
  2. 对于灾难恢复而言,RDB是非常不错的选择。因为我们可以非常轻松的将一个单独的文件压缩后再转移到其它存储介质上。
  3. 性能最大化。对于Redis的服务进程而言,在开始持久化时,它唯一需要做的只是fork出子进程,之后再由子进程完成这些持久化的工作,这样就可以极大的避免服务进程执行IO操作了
  4. 相比于AOF机制,如果数据集很大,RDB的启动效率会更高。

劣势

  1. RDB方式数据没办法做到实时持久化/秒级持久化。因为bgsave每次运行都要执行fork操作创建子进程,属于重量级操作,频繁执行成本过高。
  2. RDB文件使用特定二进制格式保存,Redis版本演进过程中有多个格式的RDB版本,存在老版本Redis服务无法兼容新版RDB格式的问题。
  3. 如果你想保证数据的高可用性,即最大限度的避免数据丢失,那么RDB将不是一个很好的选择。因为系统一旦在定时持久化之前出现宕机现象,此前没有来得及写入磁盘的数据都将丢失。
  4. 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟。

AOF

  • AOF(append only file)持久化:以独立日志的方式记录每次写命令,重启时再重新执行AOF文件中命令达到恢复数据的目的AOF的主要作用是解决了数据持久化的实时性,目前已经是Redis持久化的主流方式。

AOF执行流程如下:
在这里插入图片描述

  • 开启AOF功能需要设置配置:appendonly yes,默认不开启。AOF文件通过appendfilename配置设置,默认文件名是appendonly.aof。保存路径同RDB持久化方式一致。通过dir配置指定。
  • AOF的工作流程操作:命令写入(append)、文件同步(sync)、文件重写(rewrite)、重启加载(load),工作流程如上。
  1. 所有的写入命令会追加到aof_buf(缓冲区)中。
  2. AOF缓冲区根据对应的策略向硬盘做同步操作。
  3. 随着AOF文件越来越大,需要定期对AOF文件进行重写,达到压缩的目的。
  4. Redis服务重启时,可以加载AOF文件进行数据恢复。了解AOF工作流程。

文件同步

  • Redis提供了多种AOF缓冲区同步文件策略,由参数appendsync控制,不同值的含义不同。
  • 下表是AOF缓冲区同步文件策略
可配置值说明
always命令写入aof_buf后调用系统fsync操作同步到AOF文件,fsync完成后线程返回
everysec命令写入aof_buf后调用系统write操作,write完成后线程返回。fsync同步文件操作由专门线程每秒调用一次
no命令写入aof_buf后调用系统write操作,不对AOF文件做fsync同步,同步硬盘操作由系统负责,通常同步周期最常为30秒
  • always:每次有数据修改发生时都会写入AOF文件;
  • everysec:每秒钟同步一次,该策略为AOF的缺省策略(最常用);
  • no:从不同步。高效但是数据不会被持久化;
  • 重写AOF:若不满足重写条件时,可以手动重写,命令:bgwriteaof

系统调用writfsync说明

  • write操作会触发延迟写(delayed write)机制,Linux在内核提供页缓冲区用来提高硬盘IO性能。write操作在写入系统缓冲区后直接返回。同步硬盘操作依赖于系统调度机制,例如:缓冲区页空间写满或达到特定时间周期。同步文件之前,如果此时系统故障宕机,缓冲区内数据将丢失。
  • fsync针对单个文件操作(比如AOF文件),做强制硬盘同步,fsync将阻塞直到写入硬盘完成后返回,保证了数据持久化。
  1. 配置为always时,每次写入都要同步AOF文件,在一般的STAT硬盘上,Redis只能支持大约几百TPS写入,显然跟Redis高性能特性背道而驰,不建议配置。
  2. 配置为no,由于操作系统每次同步AOF文件的周期不可控,而且会极大每次同步硬盘的数据量,虽然提升了性能,但数据安全性无法保证。
  3. 配置为everysec,是建议的同步策略,也是默认配置,做到兼顾性能和数据安全性,理论上只有在系统突然宕机的情况下丢失1s的数据。(严格来说最多丢失1s数据是不准确的)
    在这里插入图片描述

优势

  1. 该机制可以带来更高的数据安全性,即数据持久性。Redis中提供了3种同步策略,即每秒同步、每修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,所差的是一旦系统出现宕机现象,那么这一秒钟之内修改的数据将会丢失。而每修改同步,我们可以将其视为同步持久化,即每次发生的数据变化都会被立即记录到磁盘中。可以预见,这种方式在效率上是最低的。至于无同步,无需多言,我想大家都能正确的理解它。
  2. 由于该机制对日志文件的写入操作采用的是append模式,因此在写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果我们本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据一致性的问题。
  3. 如果日志过大,Redis可以自动启用rewrite机制。即Redisappend模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性。
  4. AOF包含一个格式清晰、易于理解的日志文件用于记录所有的修改操作。事实上,我们也可以通过该文件完成数据的重建。

劣势

  1. 对于相同数量的数据集而言,AOF文件通常要大于RDB文件。RDB在恢复大数据集时的速度比AOF的恢复速度要快。
  2. 根据同步策略的不同,AOF在运行效率上往往会慢于RDB。总之,每秒同步策略的效率是比较高的,同步禁用策略的效率和RDB一样高效。

AOF重启加载流程

  • AOFRDB文件都可以用于服务器重启时的数据恢复。如图所示,表示Redis持久化文件加载流程:
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值