Redis持久化

引用文章:http://www.redis.cn/topics/persistence.html

Redis官方地址:https://redis.io/topics/persistence

Redis提供不同级别持久化方案

·RDB持久化方式能在指定时间周期内对数据进行快照存储

·AOF(Append-only file)持久化方式记录每次对Redis的写操作命令,当Redis重启,会重新执行这些命令以恢复原始数据,AOF命令遵循Redis协议追加到文件末尾,Redis还能对AOF文件进行后台重写(轮询文件),使得AOF文件的体积不至于过大。

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

·也可以同时开启两种持久化方式。当Redis重启,会优先载入AOF文件来恢复原始数据(一般AOF文件保存的数据库要比RDB文件保存的数据库完整)

RDB优点

·RDB文件十分紧凑(compact),保存某个时间及该时间以前的数据集,如:每小时保存一下数据,那么30天后,如果出问题,可以根据需求恢复不同时间版本的数据集

·非常适合备份,或灾难恢复,在出现问题后,直接传送紧凑的RDB单文件进行恢复。

·RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化Redis的性能

·与AOF相比,在恢复大的数据集时,RDB方式会更快一些

RDB缺点

·若希望Redis意外停止工作(如服务器断电)时丢失最少数据,那AOF方式更适合,虽然可配置不同的save时间点(如每5分钟数据集有100个写操作时执行持久化),但最后一次持久化后的数据更新无法保存到磁盘

·RDB需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在一些毫秒级内不能响应客户端的请求.如果数据集巨大并且CPU性能不是很好的情况下,这种情况会持续1秒,AOF也需要fork,但是你可以调节重写日志文件的频率来提高数据集的耐久度(产品能够无故障的使用较长时间或使用寿命长)

AOF优点

·AOF方式能提高Redis数据集的耐久度,可以有多种fsync策略:

完全无fsync;

每秒fsync;(默认策略),(fsync是由后台线程进行处理的,主线程会尽力处理客户端请求),一旦出现故障,你最多丢失1秒的数据

每次写fsync;

·AOF会追加日志到文件,而不需要搜索文件内容,即使由于某些原因(磁盘空间已满,写的过程中宕机等等)未执行完整的写入命令,你也也可使用Redis-check-aof工具修复这些问题

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

·AOF文件按照命令执行顺序保存对数据库执行的所有写入操作,这些写入操作以Redis协议格式保存,因此AOF文件易读性高,分析方便,同时AOF文件导出也很便捷。举个例子,如果你不小心执行了FLUSHALL命令,但只要AOF文件未被重写,那么只要停止服务器,移除AOF文件末尾的FLUSHALL命令,并重启Redis,就可以将数据集恢复到FLUSHALL执行之前的状态

AOF缺点

·对于相同的数据集来说,AOF文件的体积通常要大于RDB文件的体积(保存的是命令列表,相较于直接保存数据更占用空间)

·根据所使用的fsync策略,AOF的持久化速度可能会慢于RDB,尽管如此,每秒fsync的性能依然非常高,而关闭fsync可以让AOF的持久化速度和RDB一样快,即使在高负荷之下也是如此。不过,在写入巨量数据时,RDB能保证比较低的延迟(latency)

·bug:In the past we experienced rare bugs in specific commands (BRPOPLPUSH之类的阻塞命令) causing the AOF produced to not reproduce exactly the same dataset on reloading. This bugs are rare and we have tests in the test suite creating random complex datasets automatically and reloading them to check everything is ok, but this kind of bugs are almost impossible with RDB persistence. To make this point more clear: the Redis AOF works incrementally updating an existing state, like MySQL or MongoDB does, while the RDB snapshotting creates everything from scratch again and again, that is conceptually more robust. However - 1) It should be noted that every time the AOF is rewritten by Redis it is recreated from scratch starting from the actual data contained in the data set, making resistance to bugs stronger compared to an always appending AOF file (or one rewritten reading the old AOF instead of reading the data in memory). 2) We never had a single report from users about an AOF corruption that was detected in the real world.

如何选择哪种持久化方式?

若想达到足以媲美PostgreSQL的数据安全性,应该同时使用两种持久化功能;

若能承受数分钟内数据丢失,可只使用RDB持久化;

很多场景用户都只使用AOF持久化,但并不推荐:因为定时生成RDB快照(snapshot),非常便于进行数据备份,且RDB恢复数据集速度比AOF快,此外,使用RDB还可以避免之前提到的AOF程序的bug;

因为以上提到的种种原因,未来官方可能会将AOF和RDB整合成单个持久化模型

快照

默认地,Redis将数据库快照保存在名字为dump.rdb的二进制文件中;

可对Redis进行设置,让它在”N秒内至少有M个改动”这一条件被满足时,自动保存数据集一次(也可通过调用SAVE或者BGSAVE,手动让Redis进行数据集保存操作)

以下是实例配置:

save 900 1 #在900秒内如果键值修改过1次就快照

save 300 10 #在300秒内如果键值修改过10次就快照

save 60 10000 #在60秒内键值修改过10000次就快照

stop-writes-on-bgsave-error yes #后台备份出错时,是否禁止新的写入操作?如果不禁止容易造成数据不一致

rdbcompression yes #导出的rdb文件是否压缩

rdbchecksum yes #恢复时导入rdb文件是否检验完整性、是否检验版本是否一致

dbfilename dump.rdb #导出来得rdb文件名

dir /var/lib/redis # rdb的存放路径

此为快照(snapshotting)。

工作方式:

当Redis需要保存dump.rdb文件时,服务器执行以下操作:

1、Redis调用forks,同时拥有父进程和子进程;

2、子进程将数据集写入到一个临时RDB文件中;

3、当子进程完成对新RDB文件的写入时,Redis用新RDB文件替换原来的RDB文件,并删除旧的RDB文件(写时复制)

AOF(append-only file)

使用RDB持久化方式在Redis服务故障时,服务器将丢失最近写入,且仍未保存到快照中的数据

1.1版本开始,Redis增加了一种完全耐久的AOF持久化方式,打开AOF功能:

appendonly no #是否开启aof功能

appendfilename "appendonly.aof" #文件名

appendfsync always #只要一修改就同步至缓冲区,并同步至磁盘

appendfsync everysec #每秒将数据同步至缓冲区,并同步至磁盘

appendfsync no # redis不设定同步策略,由内核设定的参数决定是否同步

no-appendfsync-on-rewrite no # appendfsync设定为always或everysec的话,还要不要同步磁盘

auto-aof-rewrite-percentage 100 #每隔多久重构aof文件,单位秒

auto-aof-rewrite-min-size 64mb # aof文件最小为多少时重构一次aof文件。搭配上一条使用

aof-load-truncated yes #崩溃修复后自动进行全备

日志重写

由于AOF工作原理是不断将写入命令追加到文件末尾,因此随着命令不断增加,AOF文件体积也会变得越来越大。如,将一个计数器增量100次,保存命令记录就需要使用100条记录,然而实际上,只是用一条SET命令就完全能保存计数器当前的值。

对此,Redis新增特性:在不阻塞或中断客户端的前提下,对AOF进行重建(rebuild)。执行BGREWRITEAOF命令,Redis将生成新的AOF文件,此文件包含重建当前数据集所需的最少命令(如此恢复时能减少耗时)。Redis 2.2版本需要手动执行BGREWRITEAOF命令;Redis 2.4后则可自动触发AOF重写

AOF持久化fsync频率

Redis fsync(或持久化)数据方式:

·有新写入就追加命令到AOF文件就fsync一次:非常慢,但异常安全

·每秒fsync一次:足够快(和RDB持久化差不多),且故障时只会丢失一秒的数据

·从不fsync:将数据交给操作系统处理,更快,但数据丢失风险高

推荐每秒fsync一次(也是默认策略),此种策略能兼备速度和安全性。

AOF文件损坏处理方法

程序正在写入AOF文件时,服务器宕机可能会造成AOF文件出错(corrupt),那么Redis重启时会拒绝载入AOF文件,从而确保数据一致性。

此时AOF文件修复方法:

1、为现有AOF文件创建备份

2、使用”redis-check-aof修复AOF文件:/usr/local/redis/src/redis-check-aof [--fix]

3、(可选)使用diff -u对比修复后的AOF文件和原始AOF文件的备份,查看两个文件之间的不同之处

4、重启Redis服务,等待服务器载入修复后的AOF文件,并进行数据恢复

AOF工作原理:

AOF重写和RDB创建快照一样,都利用写时复制机制。

1、Redis执行fork(),此时Redis存在父进程和子进程

2、子进程开始将新AOF文件的内容写入到临时文件

3、对于新执行的写入命令,父进程将之累计到内存中,一边将这些改动追加到现有AOF文件的末尾(如此,即使重写中途宕机,现有AOF文件还是安全的)

4、当子进程完成重写工作,会发送一个信号给父进程,父进程收到信号后,将内存中所有数据追加到新AOF文件末尾

5、此时,Redis原子地用新文件替换旧文件,此后所有命令都直接追加到新AOF文件末尾

从RDB方式切换为AOF方式

Redis2.2版本后,支持热切换:

1、为最新的dump.rdb创建备份,放至安全位置

2、执行命令:

redis-cli config set appendonly yes#开启AOF功能,Redis会阻塞直到初始AOF文件创建完成为止,之后Redis会继续处理命令请求,并开始将写入命令追加到AOF文件末尾

redis-cli config set save“”#关闭RDB功能。这一步是可选的,如果你愿意的话,也可以同时使用RDB和AOF这两种持久化功能。

3、redis-cli config rewrite#重写此配置到redis.conf配置文件

4、确保命令被正确地追加AOF文件末尾

AOF与RDB间的相互作用

自Redis2.4版本起,BGSAVE执行的过程中,不可以执行BGREWRITEAOF。反过来说,在BGREWRITEAOF执行的过程中,也不可以执行BGSAVE。这可以防止两个Redis后台进程同时对磁盘进行大量的I/O操作。

如果BGSAVE正在执行,并且用户显示地调用BGREWRITEAOF命令,那么服务器将向用户回复一个OK状态,并告知用户,BGREWRITEAOF已经被预定执行:一旦BGSAVE执行完毕,BGREWRITEAOF就会正式开始。当Redis启动时,如果RDB持久化和AOF持久化都被打开了,那么程序会优先使用AOF文件来恢复数据集,因为AOF文件所保存的数据通常是最完整的

备份redis持久化后的数据

牢记一句话:确保你的数据有完整的备份

磁盘故障,节点失效,此类问题都可能让数据出现问题,没有备份计划是非常危险的,

Redis备份数据文件十分方便,由于RDB文件一旦被创建就不会进行任何修改,因此可以无阻塞,无中断的热备份。当服务器要创建一个新的RDB文件时,现将文件内容保存在一个临时文件里面,当临时文件写入完毕,程序才会将临时文件替换成原来的RDB文件(rename)。

建议使用crontab计划任务执行定期备份,如:

·每小时将RDB文件备份至一文件夹,然后每天将该目录备份至另外的服务器

·确保快照的备份都有相应的日期和时间信息,每次执行定期任务脚本时,使用find来删除过期快照,比如保存最近一周内每小时的快照

容灾备份

Redis容灾备份就是数据备份,且将这些备份复制到多个不同的数据中心,至少是不同的服务器。

要注意的是,应该自文件传送完毕后检查所传送的备份文件体积与原始文件是否相同,也可以比对文件SHA1值,来确认文件是否传送完整。

最好,创建一个监控,负责在备份文件或者传送文件出现问题是发出告警。

  • 发表于:
  • 原文链接:http://kuaibao.qq.com/s/20180424G0TZYP00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券