Redis数据持久化

什么是持久化:

通俗点:就是把redis缓存在内存中的数据保存到磁盘文件里面。

 

Redis持久化分2种:

RDB 持久化

可以在指定的时间间隔内生成数据集的时间点快照(point-in-time snapshot)。

优点:速度快,适合于用做备份,主从复制也是基于RDB持久化功能实现的。

缺点:会有数据丢失

AOF 持久化

记录服务器执行的所有写操作命令,并在服务器启动时,通过重新执行这些命令来还原数据集。 AOF 文件中的命令全部以 Redis 协议的格式来保存,新命令会被追加到文件的末尾。

优点:可以最大程度保证数据不丢

缺点:日志记录量级比较大

 

RDB 和 AOF ,我应该用哪一个?

一般来说,如果想达到足以媲美 PostgreSQL 的数据安全性, 你应该同时使用两种持久化功能。

如果你非常关心你的数据,但仍然可以承受数分钟以内的数据丢失, 那么你可以只使用 RDB 持久化。

有很多用户单独使用AOF,但是我们并不鼓励这样,因为时常进行RDB快照非常方便于数据库备份,启动速度也较之快,还避免了AOF引擎的bug。

注意:基于这些原因,将来我们可能会统一AOF和RDB为一种单一的持久化模型(长远计划)。

下面的部分将分别介绍两种持久化模型。

 

1 . RDB 持久化:

rdb持久化核心配置参数:

[root@redis01 redis]#vim /nosql/6379/redis.conf

dir /nosql/6379

dbfilename dump.rdb

save 900 1

save 300 10

save 60 10000

 

配置分别表示:

900秒(15分钟)内有1个更改

300秒(5分钟)内有10个更改

60秒内有10000个更改

 

RDB持久化高级配置:

stop-writes-on-bgsave-error yes

rdbcompression yes

rdbchecksum yes

dbfilename dump.rdb

dir ./

以上配置分别表示:

后台备份进程出错时,主进程停不停止写入? 主进程不停止容易造成数据不一致

导出的rdb文件是否压缩 如果rdb的大小很大的话建议这么做

导入rbd恢复时数据时,要不要检验rdb的完整性 验证版本是不是一致

导出来的rdb文件名

rdb的放置路径

 

Rdb快照的运作方式:

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

Redis 调用 fork() ,同时拥有父进程和子进程。

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

当子进程完成对新 RDB 文件的写入时,Redis 用新 RDB 文件替换原来的 RDB 文件,并删除旧的 RDB 文件。

这种工作方式使得 Redis 可以从写时复制(copy-on-write)机制中获益。

 

2: AOF 持久化(append-only log file)

appendonly  yes/no

appendfsync always

appendfsync everysec

appendfsync no

配置分别表示:

是否打开aof日志功能

每1个命令,都立即同步到aof

每秒写1次

写入工作交给操作系统,由操作系统判断缓冲区大小,统一写入到aof.

 

AOF持久化高级配置:

no-appendfsync-on-rewrite yes/no

auto-aof-rewrite-percentage 100

auto-aof-rewrite-min-size 64mb

配置分别表示:

正在导出rdb快照的过程中,要不要停止同步aof

aof文件大小比起上次重写时的大小,增长率100%时重写,缺点:业务开始的时候,会重复重写多次。

aof文件,至少超过64M时,重写

 

我们这里就开启简单的配置就行:

[root@redis01 redis]#vim /nosql/6379/redis.conf

appendonly yes

appendfsync everysec

 

AOF持久化工作原理:

只进行追加操作的文件(append-only file,AOF) 
快照功能并不是非常耐久:如果 Redis 因为某些原因而造成故障停机,那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。尽管对于某些程序来说,数据的耐久性并不是最重要的考虑因素,但是对于那些追求完全耐久能力的程序员来说,快照功能就不太适用了。

从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化。 
你可以通过修改配置文件来打开 AOF 功能: 
appendonly yes 
从现在开始,每当 Redis 执行一个改变数据集的命令式(比如 SET),这个命令就会被追加到 AOF 文件的末尾。 
这样的话,当redis重新启动时,程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的

 

AOF 重写 :

因为 AOF 的运作方式是不断地将命令追加到文件的末尾,所以随着写入命令的不断增加, AOF 文件的体积也变得越来越大。举个例子,如果你对一个计数器调用了 100 次 INCR ,那么仅仅是为了保存这个计数器的当前值, AOF 文件就需要使用 100 条记录。然而在实际上,只使用一条 SET 命令已经足以保存计数器的当前值了,其余 99 条记录实际上都是多余的。

为了处理这种情况, Redis 支持一种有趣的特性:可以在不断服务客户端的情况下,对 AOF 文件进行重建。执行 BGREWRITEAOF 命令, Redis 将生产一个新的 AOF 文件,这个文件包含重建当前数据集所需的最少命令。

 

AOF 有多耐久:

你可以配置 Redis 多久才将数据 fsync 到磁盘一次。 
有三个选项: 
每次有新命令追加到 AOF 文件时就执行一次 fsync :非常慢,也非常安全。 
每秒 fsync 一次:足够快(和使用 RDB 持久化差不多,)并且在故障时只会丢失1秒钟的数据。 
从不 fsync :将数据交给操作系统来处理。更快,也更不安全的选择。 
推荐(并且也是默认)的措施为每秒 fsync 一次,这种 fsync 策略可以兼顾速度和安全性。 
总是 fsync 的策略在实际使用中非常慢,即使在 Redis2.0 对相关的程序进行了改进之后仍是如此。频繁调用 fsync 注定了这种策略不可能快得起来。

 

如果 AOF 文件出错了,怎么办??:

服务器可能在程序正在对AOF文件进行写入时停机,如果停机造成了AOF文件出错,那么 Redis 在重启时会拒绝载入这个 AOF 文件,从而确保数据的一致性不会被破坏。

当发生 AOF 文件出错时,可以用以下方法来修复出错的 AOF 文件:
1、为现有的 AOF 文件创建一个备份。
2、使用 Redis 附带的 redis-check-aof 程序,对原来的AOF 文件进行修复。
redis-check-aof  --fix
3、使用 diff -u  对比修复后的 AOF 文件和原始 AOF 文件的备份,查看两个文件之间的不同之处。
4、重启 Redis 服务器,等待服务器载入修复后的 AOF 文件,并进行数据恢复。

列子:

[root@redis01 redis]# redis-check-aof appendonly.aof.bak

AOF analyzed: size=77, ok_up_to=77, diff=0

AOF is valid

[root@redis01 redis]#diff -u  appendonly.aof  appendonly.aof.bak

 

3 .  RDB 和 AOF 之间的相互作用 :

 

在版本号大于等于 2.4 的 Redis 中, BGSAVE 执行的过程中,不可以执行 BGRWRITEAOF 。 反过来说,在 BGRWRITEAOF 执行的过程中,也不可以执行 BGSAVE 。

这可以防止两个 Redis 后台进程同时对磁盘进行大量的 I/O 操作。 
如果 BGSAVE 正在执行,并且用户显示地调用 BGRWRITEAOF 命令,那么服务器将向用户回复一个 OK 状态,并告知用户, BGRWRITEAOF 已经被预定执行; 一旦 BGSAVE 执行完毕, BGRWRITEAOF 就会正式开始。

当 Redis 启动时,如果 RDB 持久化和 AOF 持久化都被打开了,那么程序会优先使用 AOF 文件来恢复数据集,因为 AOF 文件所保存的数据通常是最完整的。

 

4 .  备份 Redis 数据:

对于数据备份是非常友好的,因为你可以在服务器运行的时候对 RDB 文件进行复制: RDB 文件一旦被创建,就不会进行任何修改。

当服务器要创建一个新的 RDB 文件时,它先将文件的内容保存在一个临时文件里面,当临时文件写入完毕时,程序才使用临时文件替换原来的 RDB 文件。

这也就是说,无论何时, 复制 RDB 文件都是绝对安全的。