您的位置:首页 > 数据库 > Redis

Redis持久化

2016-09-21 14:25 211 查看
Redis是一个基于内存的数据结构存储系统,因此Redis存储的所有数据都在内存中。我们都清楚,若将所有数据都存储在内存中,当重启Redis后,所有存储在内存中的数据均会丢失。但是在某些场景下,我们需要Redis重启后依然保留存储的数据【如将Redis作为数据库使用】,所幸Redis提供了2种持久化方式,分别是RDB方式和AOF方式。

其中RDB方式会根据指定规则,在达到特定的条件下将内存中数据生成快照同步到RDB文件中;而AOF方式会在每次执行命令后,将命令记录到AOF文件中。此两种持久化方式可以单独使用,也可以配合使用。

鉴于AOF文件会比RDB文件丢失更少的数据,即数据更完整,因此若同时开启了RDB和AOF两种持久化功能,在启动Redis时,Redis会使用AOF文件来恢复数据。

RDB方式

Redis默认会将RDB快照文件存储在当前Redis进程的工作目录中,快照文件名为dump.rdb【可以通过修改配置文件中的dirdbfilename配置项来修改快照文件的存储目录和文件名】

Redis生成RDB快照文件的过程如下:

1、Redis使用fork函数为当前Redis进程生成一个子进程,子进程用于生成快照【fork出来的子进程和父进程使用写时复制策略共享同一内存空间】。

2、父进程继续接收并处理客户端的命令请求,子进程为Redis内存数据创建快照,写入到临时文件中

3、当子进程完成所有数据的写入,然后将临时文件覆盖原来旧的RDB文件,到此,快照文件生成完成。【从中可以看到直到新的快照生成完成才会替换就的快照文件,因此RDB快照文件在任何时刻都是完整的】

Redis会在以下4种情况下对内存数据生成快照文件同步到磁盘中:

1、根据配置文件中配置的规则进行自动快照【在配置文件中配置 save <seconds> <changes> 选项,表示当时间在seconds秒内被修改的键大于等于changes个时,触发自动快照操作,可以同时存在多个save配置,多个save配置间是“或”的关系,即只要任意符合一个条件就会触发自动快照操作】

2、执行SAVE或者BGSAVE命令【其中SAVE命令会同步的进行快照操作,从而造成在快照操作过程中会阻塞所有客户端的请求,导致Redis在此过程中不响应】

3、执行FLUSHALL命令

4、执行复制(replication)时【在开启Redis主从复制功能的情况下】

AOF方式

默认情况下,Redis并不会开启AOF持久化功能,因此需要修改配置文件中appendonly配置项的值为yes来开启AOF持久化功能。AOF文件的存储位置和RDB文件的存储位置相同,因此都可以通过配置文件的dir配置项进行配置,同时可以通过appendfilname配置项配置AOF文件的文件名。在启动Reids服务时,Reids会逐个执行AOF文件中的命令,将磁盘中的数据加载到内存中。

AOF文件中存储的内容就是客户端向Redis服务端发送的原始通信协议的内容。Redis服务会将其接收到的所有命令到添加到AOF文件中,因此随着时间的推移Redis服务接收的命令越来越多,AOF文件的大小也会随之增大。

AOF文件示例:

[ojh@localhost ~]$ redis-cli
127.0.0.1:6379> set a 1
OK
127.0.0.1:6379> set a 2
OK
127.0.0.1:6379> set a 3
OK
127.0.0.1:6379>
[ojh@localhost ~]$
[ojh@localhost ~]$ cat appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
set
$1
a
$1
1
*3
$3
set
$1
a
$1
2
*3
$3
set
$1
a
$1
3


AOF文件重写

从上面示例中可以看到Redis会把其接收到的每一条命令都写入到AOF文件中,具体看上面示例中的三条命令,就数据恢复来说,第一、二两条命令是没意义的,这些冗余没意义的命令记录在AOF文件中,导致AOF文件的空间有可能会远大于内存中的实际数据,并且增加数据恢复的时间,因此Redis提供了AOF文件重写机制来重写AOF文件,删除冗余没意义的命令。

Redis提供了如下两种方式触发AOF文件的重写:

1、通过配置文件中auto-aof-rewrite-percentageauto-aof-rewrite-min-size两个配置项自动触发AOF文件重写;【其中auto-aof-rewrite-percentage表示当前AOF文件大小超过上一次重写时AOF文件大小的百分之多少时,自动触发重写;auto-aof-rewrite-min-size表示当AOF文件占用空间小于此配置值时,即使满足auto-aof-rewrite-percentag配置的条件也不触发AOF文件重写】

2、执行BGREWEITEAOF命令触发AOF文件重写。

AOF文件重写后的内容:【从下面内容中可以看到冗余的命令已经被删除了】

[ojh@localhost ~]$ redis-cli
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
127.0.0.1:6379>
[ojh@localhost ~]$ cat appendonly.aof
*2
$6
SELECT
$1
0
*3
$3
SET
$1
a
$1
3


上面AOF文件内容的格式为Redis统一请求协议:*字符串数组长度\r\n$字符串1长度\r\n字符串1实际内容\r\n…

解析如下:

*3          //表示此命令有3个字符串
$3         //表示第一字符串长度为3个字符
SET         //第一个字符串实际内容
$1         //表示第二个字符串长度为1个字符
a           //第二个字符串实际内容
$1         //同上面解析
3           //同上面解析
//因此上面内容实际是命令:SET a 3


注意:现代操作系统为了提高磁盘读写速度,都会在实际写入数据到磁盘前,先将数据写入到一个缓冲区中,然后定时将缓冲区内容同步到磁盘中。在Redis写AOF文件时,若Redis已经将接收的命令写入到磁盘缓冲中,但是操作系统还没实际将数据同步到磁盘中,此时若系统出现故障导致磁盘缓冲数据丢失,就会导致Redis AOF文件出现数据丢失的情况。

Redis配置文件提供了appendfsync配置项来主动触发操作系统将磁盘缓冲中的数据同步到磁盘中。

appendfsync配置项的可选值及其含义:

# appendfsync always
appendfsync everysec
# appendfsync no
//其中 always 表示每次执行AOF文件写入到回执行同步,这是最安全的方式,但是效率最低
//everysec 表示没秒钟触发同步操作,将缓冲区内容同步到磁盘中,这是默认值
//no 表示不主动触发磁盘缓冲区的同步操作,有操作系统根据自己的策略进行同步,效率最快,但是最不安全
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  redis 数据库