Redis的持久化

Redis的持久化机制

两种方式:快照(snapshotting,RDB);只追加文件 (append-only-file,AOF)

RDB Redis DataBase

AOF append only file

Redis可以通过创建快照来获得存储在内存里面的数据在某个时间点上的副本。Redis创建快照之后,可以对快照进行备份,可以将快照复制到其他服务器从而创建具有相同数据的服务器副本(Redis主从结构,主要用来提高Redis性能),还可以将快照留在原地以便重启服务器的时候使用。

在指定的时间间隔内将内存中的数据集快照写入磁盘,恢复时是将快照文件直接读到内存里

Redis会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的,这就确保了极高的性能

如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点是最后一次持久化后的数据可能丢失

Fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程

RDB保存的是dump.rdb文件

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

save 900 1    #在900秒(15分钟)之后,如果至少有1个key发生变化,Redis就会自动触发BGSAVE命令创建快照

save 300 10  #在300秒(5分钟)之后,如果至少有10个key发生变化,Redis就会自动触发BGSAVE命令创建快照

save 60 10000   #在60秒(1分钟)之后,如果至少有10000个key发生变化,Redis就会自动触发BGSAVE命令创建快照

snapshotting

Save the DB on disk:save <seconds> <changes>

In the example below the behaviour will be to save:

after 900 sec (15min)if at least 1 key changed

after 300 sec (5min)if at least 10 keys changed

after 60 sec if at least 10000 keys changed

 

flushall、shutdown的时候,会迅速生成dump.rdb文件持久化到磁盘

flushall会自动生成空文件并立即持久化到磁盘

-->save  自动生成dump.rdb文件持久化到磁盘

 

Stop-writes-on-bgsave-error:如果后台保存出错了,前台要停止写  默认配置为yes

rdbcompression:对于存储到磁盘中的快照,可以设置是否进行压缩存储。如果是的话,redis会采用LZF算法进行压缩。如果不想消耗CPU来进行压缩的话,可以设置为关闭此功能。  (但压缩会多耗点CPU)

rdbchecksum:在存储快照后,还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能损耗,如果希望获取到最大的性能提升,可以关闭此功能

 

如何触发RDB快照:

配置文件中的默认的快照配置    冷拷贝后重新使用  可以cp dump.rdb dump_new.rdb  主机拷贝到备机

命令save或者是bgsave     区别

save:只管保存,其他不管,全部阻塞     

bgsave:redis会在后台异步进行快照操作,快照同时还可以响应客户端请求。可以通过lastsave命令获取最后一次成功执行快照的时间

执行flushall命令,也会产生dump.rdb文件,但里面是空的,无意义

 

如何恢复

将备份文件(dump.rdb)移动到redis安装目录并启动服务即可

CONFIG GET dir 获取目录

 

优势:

适合大规模的数据恢复;对数据完整性和一致性要求不高

劣势:

在一定间隔时间做一次备份,所以如果redis意外down掉的话,就会丢失最后一次快照后的所有修改

Fork的时候,内存中的数据被克隆了一份,2倍的膨胀性能需要考虑

 

如何停止:动态停止RDB保存规则的方法redis-cli config set save ""

 

RDB小结:

内存中的数据对象-->(rdbSave)-->磁盘中的RDB文件

磁盘中的RDB文件-->(rdbLoad)-->内存中的数据对象

  • RDB是一个非常紧凑的文件
  • RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能
  • 与AOF相比,在恢复大的数据集的时候,RDB方式会更快一些
  • 数据丢失风险大
  • RDB需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级不能响应客户端请求

 

AOF(Append Only File)持久化

与快照持久化相比,AOF持久化的实时性能更好,因此已成为主流的持久化方案。默认情况下,Redis没有开启AOF方式的持久化,可以通过appendonly参数开启:appendonly yes

appendfilename:appendonly.aof

 

是什么:以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复操作

 

开启AOF持久化后每执行一条会更改Redis中的数据的命令,Redis就会将该命令写入硬盘中的AOF文件。AOF文件的保存位置和RDB文件的位置相同,都是通过dir参数设置的,默认的文件名是appendonly.aof

在Redis的配置文件中存在三种不同的AOF持久化方式,它们分别是:

appendfsync always  #每次有数据修改发生时都会写入AOF文件,这样会严重降低Redis的速度  同步持久化,性能较差但数据完整性比较好

appendfsync everysec  #每秒钟同步一次,显示地将多个写命令同步到硬盘 

            出厂默认推荐,异步操作,每秒记录,如果一秒内宕机,数据丢失

appendfsync no  #让操作系统决定何时进行同步

 

为了兼顾数据和写入性能,用户可以考虑appendfsync everysec选项,让Redis每秒同步一次AOF文件,Redis性能几乎没受到任何影响。而且这样即使出现系统崩溃,用户最多只会丢失一秒之内产生的数据。当硬盘忙于执行写入操作的时候,Redis还会优雅地放慢自己的速度以便适应硬盘的最大写入速度。

 

appendonly文件损坏:无法启动          修复:redis-check-aof  --fix  appendonly.aof

appendonly.aof、dump.rdb  可以共存,先加载的是aof文件          AOF和RDB持久化机制可以共存

 

AOF启动/修复/恢复

正常恢复        启动:设置Yes,修改默认的appendonly no,改为yes

      将有数据的aof文件复制一份保存到对应目录(config get dir)

      恢复:重启redis然后重新加载

异常恢复        启动:设置Yes

      修复:Redis-check-aof --fix进行修复

      恢复:重启Redis然后重新加载

 

Rewrite 重写

      是什么:AOF采用文件追加方式,文件会越来越大为避免出现此种情况,新增了重写机制,当AOF文件的大小超过所设定的阈值时,Redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集,可以使用命令bgrewriteaof

      重写原理:AOF文件持续增长而过大时,会fork出一条新进程来将文件重写(也是先写临时文件最后再rename),遍历新进程的内存中数据,每条记录有一条的Set语句。重写aof文件的操作,并没有读取旧的AOF文件,而是将整个内存中的数据库内容用命令的方式重写了一个新的AOF文件,这点和快照有点类似

      触发机制:Redis会记录上次重写时的AOF大小,默认配置是当AOF文件大小是上次rewrite后大小的一倍且文件大于64M时触发

      No-appendfsync-on-rewrite:重写时是否可以运用Appendfsync。用默认no即可,保证数据安全性

      auto-aof-rewrite-percentage  100

      auto-aof-rewrite-min-size 64MB    设置重写的基准值

 

  优势:每秒同步;每修改同步;不同步

  劣势:相同数据集的数据而言aof文件要远大于rdb文件,恢复速度慢于rdb

     AOF运行效率要慢于rdb,每秒同步策略效率较好,不同步效率和rdb相同

 

  AOF重写是通过读取数据库中的键值对来实现的,程序无须对现有AOF文件进行任何读入、分析或者写入操作

 

  在执行bgrewriteaof命令时,Redis服务器会维护一个AOF重写缓冲区,该缓冲区会在子进程创建新AOF文件期间,记录服务器执行的所有命令。当子进程完成创建新AOF文件的工作之后,服务器会将重写缓冲区中的所有内容追加到新AOF文件的末尾,使得新旧两个AOF文件所保存的数据库状态一致。最后,服务器用新的AOF文件替换旧的AOF文件,以此来完成AOF文件重写操作。

 

AOF总结:

客户端-->(命令请求)-->服务器-->(网络协议格式的命令内容)-->AOF文件

AOF文件是一个只进行追加的日志文件

Redis可以在AOF文件体积变得过大时,自动地在后台对AOF进行重写

AOF文件有序地保存了对数据库执行的所有写入操作,这些写入操作以Redis协议的格式保存,因此AOF文件的内容非常容易被人读懂,对文件进行分析也很轻松

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

根据所使用的fsync策略,AOF的速度可能会慢于RDB

 

which one

RDB持久化方式能够在指定的时间间隔内对数据进行快照存储

AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾

Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大

只做缓存:如果只希望数据在服务器运行的时候存在,也可以不使用任何持久化方式,

同时开启两种持久化方式

 

 

 

Redis4.0对于持久化机制的优化

Redis4.0开始支持RDB和AOF的混合持久化(默认关闭,可以通过配置项aof-use-rdb-preamble开启)

如果把混合持久化打开,AOF重写的时候就直接把RDB的内容写到AOF文件开头。这样做的好处是可以结合RDB和AOF的优点,快速加载同时避免丢失过多的数据。当然缺点也是有的,AOF里面的RDB部分是压缩格式不再是AOF格式,可读性较差。

 

posted @ 2020-04-10 20:54  LinBupt  阅读(153)  评论(0编辑  收藏  举报