Redis 提供了不同级别的持久化方式:
- RDB持久化方式能够在指定的时间间隔能对你的数据进行快照存储.
- AOF持久化方式记录每次对服务器写的操作,当服务器重启的时候会重新执行这些命令来恢复原始的数据,AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大.
- 如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式.
- 你也可以同时开启两种持久化方式, 在这种情况下, 当redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整.
- 最重要的事情是了解RDB和AOF持久化方式的不同,让我们以RDB持久化方式开始:
1、RDB机制
- 触发机制有三种:save、bgsave、自动化
- save触发方式:
该命令会阻塞当前Redis服务器,执行save命令期间,Redis不能处理其他命令,直到RDB过程完成为止,Redis会返回OK(一般不会使用) - bgsave触发方式:
执行该命令时,Redis会在后台异步进行快照操作,快照同时还可以响应客户端请求;
具体操作是Redis进程执行fork操作创建子进程,RDB持久化过程由子进程负责,完成后自动结束。阻塞只发生在fork阶段,一般时间很短。基本上 Redis 内部所有的RDB操作都是采用 bgsave 命令。 - 自动触发:
自动触发是由我们的配置文件来完成的(最终执行的是bgsave)。在redis.conf配置文件中,里面有如下配置,我们可以去设置:
# 这里是用来配置触发 Redis的 RDB 持久化条件,也就是什么时候将内存中的数据保存到硬盘,比如“save m n”。表示m秒内数据集存在n次修改时,自动触发bgsave。
# 表示900 秒内如果至少有 1 个 key 的值变化,则保存
save 900 1
# 表示300 秒内如果至少有 10 个 key 的值变化,则保存
save 300 10
# 表示60 秒内如果至少有 10000 个 key 的值变化,则保存
save 60 10000
# 默认值为yes。当启用了RDB且最后一次后台保存数据失败,Redis是否停止接收数据。
stop-writes-on-bgsave-error yes
# 默认值是yes。对于存储到磁盘中的快照,可以设置是否进行压缩存储。
rdbcompression yes
# 默认值是yes。在存储快照后,我们还可以让redis使用CRC64算法来进行数据校验,但是这样做会增加大约10%的性能消耗,如果希望获取到最大的性能提升,可以关闭此功能。
rdbchecksum yes
# 设置快照的文件名,默认是 dump.rdb
dbfilename dump.rdb
# 设置快照文件的存放路径,这个配置项一定是个目录,而不能是文件名。
dir /usr/local/redis/data
- RDB的优点
- RDB是一个非常紧凑的文件,它保存了某个时间点的数据集,非常适用于数据集的备份,比如你可以在每个小时报保存一下过去24小时内的数据,同时每天保存过去30天的数据,这样即使出了问题你也可以根据需求恢复到不同版本的数据集.
- RDB是一个紧凑的单一文件,很方便传送到另一个远端数据中心或者亚马逊的S3(可能加密),非常适用于灾难恢复.
- RDB在保存RDB文件时父进程唯一需要做的就是fork出一个子进程,接下来的工作全部由子进程来做,父进程不需要再做其他IO操作,所以RDB持久化方式可以最大化redis的性能.
- 与AOF相比,在恢复大的数据集的时候,RDB方式会更快一些.
- RDB的缺点
- 如果你希望在redis意外停止工作(例如电源中断)的情况下丢失的数据最少的话,那么RDB不适合你.虽然你可以配置不同的save时间点(例如每隔5分钟并且对数据集有100个写的操作),是Redis要完整的保存整个数据集是一个比较繁重的工作,你通常会每隔5分钟或者更久做一次完整的保存,万一在Redis意外宕机,你可能会丢失几分钟的数据.
- RDB 需要经常fork子进程来保存数据集到硬盘上,当数据集比较大的时候,fork的过程是非常耗时的,可能会导致Redis在毫秒级内不能响应客户端的请求.如果数据集巨大并且CPU性能不是很好的情况下,这种情况会持续1秒,AOF也需要fork,但是你可以调节重写日志文件的频率来提高数据集的耐久度.
2、AOF机制
- AOF机制的介绍及相关配置
- 以日志的形式来记录每个写操作,将Redis执行过的所有写指令记录下来(读操作不记录),
只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据,换言之,redis
重启的话就根据日志文件的内容将写指令从前到后执行一次以完成数据的恢复工作 - AOF的方式也同时带来了另一个问题。持久化文件会变的越来越大。为了压缩aof的持久化文件。redis提供了bgrewriteaof命令。将内存中的数据以命令的方式保存到临时文件中,同时会fork出一条新进程来将文件重写。
# 默认不开启(appendonly no)
appendonly yes
# 文件名
appendfilename "appendonly.aof"
# 执行频率always(每一次写操作都执行)、evrysec(每秒执行一次)、no(不执行);一般使用evrysec
appendfsync evrysec
# aof重写操作会对磁盘造成大量的I/O操作,若在这期间主进程仍然写aof文件,主进程可能会因此发生阻塞(设置为no的情况),但是不会丢失数据。
# 如果设置为yes,这说明并没有执行磁盘操作,只是写入了缓冲区,因此这样并不会造成阻塞(因为没有竞争磁盘),
# 但是如果这个时候redis挂掉,就会丢失数据。在linux的操作系统的默认设置下,最多会丢失30s的数据。
no-appendfsyc-on-rewrite no
# 代表当前AOF文件空间和上一次重写后AOF文件空间的比值,下面的100表示超过上次aof文件的100%则触发重写
auto-aof-rewrite-percentage 100
# 表示运行AOF重写时文件最小体积,默认 为64MB。当前aof文件大于这个值,则重写
auto-aof-rewrite-min-size 64mb
# 当设置成yes时,redis会忽略最后一条可能存在问题的操作日志,并发出一个日志来通知用户;
# 当设置成no时,aof文件有问题,直接报错,用户需要手动redis-check-aof来对aof文件修复。
aof-load-truncated yes
# 设置为yes,开启混合持久化模式,重写aof时,会使用rdb持久化模式将共享的内存副本全量的以RDB方式写入aof文件
# 然后在将重写缓冲区的增量命令以AOF方式写入到文件,写入完成后通知主进程更新统计信息,
# 并将新的含有RDB格式和AOF格式的AOF文件替换旧的的AOF文件。最终的aof文件形式:[RDB file][AOF tail]
aof-use-rdb-preamble yes
- AOF 优点
- AOF的每秒fsync策略可以保证Redis就算宕机,最大也只丢失1秒的数据。
- Redis 可以在 AOF 文件体积变得过大时,自动地在后台对 AOF 进行重写。
- AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析(parse)也很轻松。
- AOF 缺点
- 对于相同的数据集来说,AOF 文件的体积通常要大于 RDB 文件的体积。
- 根据所使用的 fsync 策略,AOF 的速度可能会慢于 RDB 。 在一般情况下, 每秒 fsync 的性能依然非常高, 而关闭 fsync 可以让 AOF 的速度和 RDB 一样快, 即使在高负荷之下也是如此。 不过在处理巨大的写入操作时,RDB 可以提供更有保证的最大延迟时间(latency)。
- 曾经恢复数据出现过bug
3、如何选择使用哪种持久化方式?
一般来说, 如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。
如果你非常关心你的数据, 但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。
有很多用户都只使用 AOF 持久化, 但我们并不推荐这种方式: 因为定时生成 RDB 快照(snapshot)非常便于进行数据库备份, 并且 RDB 恢复数据集的速度也要比 AOF 恢复的速度要快, 除此之外, 使用 RDB 还可以避免之前提到的 AOF 程序的 bug 。
借鉴于:http://www.redis.cn/topics/persistence.html
这个官方文档(中文版),讲得很是详细,建议全文阅读。本文只借鉴文档部分内容,加了在实际生产中的配置讲解。