Redis持久化存储

一、概述

Redis支持两种持久化方式:

Redis的强大性能很大程度上都是因为所有数据都是存储在内存中的,然而当Redis重启后,所有存储在内存中的数据将会丢失,在很多情况下是无法容忍这样的事情的。所以,我们需要将内存中的数据持久化!典型的需要持久化数据的场景如下:

(1)RDB:按照指定的规则“定期”将内存中的数据存储到硬盘上;

  1. 将Redis作为数据库使用;
  2. 将Redis作为缓存服务器使用,但是缓存miss后会对性能造成很大影响,所有缓存同时失效时会造成服务雪崩,无法响应。

(2)AOF:定期或者在每次执行命令后将命令本身记录下来;

本文介绍Redis所支持的两种数据持久化方式。

两种持久化方式可以单独使用一种,也可以二者同时使用。

二、Redis数据持久化

一、RDB

Redis支持两种数据持久化方式:RDB方式和AOF方式。前者会根据配置的规则定时将内存中的数据持久化到硬盘上,后者则是在每次执行写命令之后将命令记录下来。两种持久化方式可以单独使用,但是通常会将两者结合使用。

RDB方式的持久化是通过对内存中的数据进行快照完成的,当符合一定条件时,Redis会自动将内存中的所有数据生成一份副本并存储在硬盘上。

1、RDB方式

RDB触发机制:

RDB方式的持久化是通过快照的方式完成的。当符合某种规则时,会将内存中的数据全量生成一份副本存储到硬盘上,这个过程称作”快照”,Redis会在以下几种情况下对数据进行快照:

1、根据配置规则进行自动快照,配置文件中SNAPSHOTTING部分可设置;

  1. 根据配置规则进行自动快照;
  2. 用户执行SAVE, BGSAVE命令;
  3. 执行FLUSHALL命令;
  4. 执行复制(replication)时。

2、用户执行SAVE或BGSAVE;

执行快照的场景

3、执行FLUSHALL命令;

(1)根据配置自动快照

4、执行复制(replication)时。

Redis允许用户自定义快照条件,当满足条件时自动执行快照。缺省情况下,Redis把数据快照存放在磁盘上的二进制文件中,文件名为dump.rdb,此外,我们也可以通过配置文件来修改Redis服务器dump快照的频率,在打开redis.windows.conf文件之后,我们搜索save,可以看到下面的配置信息:

配置:

澳门新葡亰赌995577 1

rdbcompression:是否在 dump .rdb 数据库的时候使用 LZF
压缩字符串,默认都设为 yes,如果你希望保存子进程节省点cpu,你就设置它为
no,不过这个数据集可能就会比较大

注意最后三行,分别表示:

rdbchecksum:是否校验rdb文件,从rdb格式的第五个版本开始,在rdb文件的末尾会带上CRC64的校验和,这跟有利于文件的容错性,但是在保存rdb文件的时候,会有大概10%的性能损耗,所以如果你追求高性能,可以关闭该配置。

在900秒(15分钟)之后,如果至少有1个key发生变化,则dump内存快照;

dbfilename:设置dump文件的名字。

在300秒(5分钟)之后,如果至少有10个key发生变化,则dump内存快照;

dir:rdb文件输出路径。

在60秒(1分钟)之后,如果至少有10000个key发生变化,则dump内存快照。

save:save 900 1
表示在900秒内如果有一个key被操作了,就执行保存快照,可以设置多个条件,各个条件彼此之间是或的关系,如果要禁用,将条件都删除,写成save
“”即可。

每个快照条件独占一行,他们之间是或(||)关系,只要满足任何一个就进行快照。上面配置save后的第一个参数T是时间,单位是秒,第二个参数M是更改的键的个数,含义是:当时间T内被更改的键的个数大于M时,自动进行快照。比如save 900 1的含义是15分钟内(900s)被更改的键的个数大于1时,自动进行快照操作。

原理:

(2)执行SAVE或BGSAVE命令

1、SAVE:

除了让Redis自动进行快照外,当我们需要重启,迁移,备份Redis时,我们也可以手动执行SAVE或BGSAVE命令主动进行快照操作。

Save是在Redis进程中执行的,由于Redis是单线程实现,所以当save命令在执行时会阻塞Redis服务器一直到该命令执行完成为止。

SAVE命令:当执行SAVE命令时,Redis同步进行快照操作,期间会阻塞所有来自客户端的请求,所以放数据库数据较多时,应该避免使用该命令;

2、BGSAVE:

BGSAVE命令:从命令名字就能看出来,这个命令与SAVE命令的区别就在于该命令的快照操作是在后台异步进行的,进行快照操作的同时还能处理来自客户端的请求。执行BGSAVE命令后Redis会马上返回OK表示开始进行快照操作,如果想知道快照操作是否已经完成,可以使用LASTSAVE命令返回最近一次成功执行快照的时间,返回结果是一个Unix时间戳。

bgsave命令会先fork出一个子进程,然后在子进程中生成RDB文件。由于在子进程中执行IO操作,所以bgsave命令不会阻塞Redis服务器进程,Redis服务器进程在此期间可以继续对外提供服务。

(3)执行FLUSHALL命令

具体过程如下:

当执行FLUSHALL命令时,Redis会清除数据库中的所有数据。需要注意的是:不论清空数据库的过程是否触发了自动快照的条件,只要自动快照条件不为空,Redis就会执行一次快照操作,当没有定义自动快照条件时,执行FLUSHALL命令不会进行快照操作。

(1)Redis使用fork函数复制一份当前进程(父进程)的副本(子进程);

(4)执行复制

(2)父进程继续接受并处理客户端发来的命令,而子进程开始将内存中的数据写入硬盘中的临时文件;

当设置了主从模式时,Redis会在复制初始化时进行自动快照。

(3)当子进程写入完所有数据后会用该临时文件替换旧的RDB文件,至此,一次快照操作完成。

快照原理

在执行fork的时候,操作系统(类Unix)会使用写时复制(copy-on-write)策略,即fork函数发生的一刻,父子进程共享同一内存数据,当父进程要更改其中某片数据时(如执行一个写命令),操作系统会将该片数据复制一份以保证子进程的数据不受影响,所以新的RDB文件存储的是执行fork一刻的内存数据。

Redis默认会将快照文件存储在Redis当前进程的工作目录的dump.rdb文件中,可以通过配置文件中的dir和dbfilename两个参数分别指定快照文件的存储路径和文件名,默认的存储路径和文件名如下图所示:

二、AOF

澳门新葡亰赌995577 2

当使用Redis存储非临时数据时,一般需要打开AOF持久化来降低进程终止导致的数据丢失。AOF可以将Redis执行的每一条写命令追加到硬盘文件中,这一过程显然会降低Redis性能,但是大部分情况下这个影响是可以被接受的,另外可以使用较快的硬盘以提高AOF的性能。

快照执行的过程如下:

配置:

(1)Redis使用fork函数复制一份当前进程(父进程)的副本(子进程);
(2)父进程继续处理来自客户端的请求,子进程开始将内存中的数据写入硬盘中的临时文件;
(3)当子进程写完所有的数据后,用该临时文件替换旧的RDB文件,至此,一次快照操作完成。

appendonly:yes为启用AOF,no为关闭AOF

需要注意的是:

appendfilename:AOF文件名

在执行fork的时候操作系统(类Unix操作系统)会使用写时复制(copy-on-write)策略,即fork函数发生的一刻,父进程和子进程共享同一块内存数据,当父进程需要修改其中的某片数据(如执行写命令)时,操作系统会将该片数据复制一份以保证子进程不受影响,所以RDB文件存储的是执行fork操作那一刻的内存数据。所以RDB方式理论上是会存在丢数据的情况的(fork之后修改的的那些没有写进RDB文件)。

AOF文件保存路径跟RDB文件相同,都是通过dir来设置

通过上述的介绍可以知道,快照进行时是不会修改RDB文件的,只有完成的时候才会用临时文件替换老的RDB文件,所以就保证任何时候RDB文件的都是完整的。这使得我们可以通过定时备份RDB文件来实现Redis数据的备份。RDB文件是经过压缩处理的二进制文件,所以占用的空间会小于内存中数据的大小,更有利于传输。

auto-aof-rewrite-percentage:aof自动重写配置。当目前aof文件大小超过上一次重写的aof文件大小的百分之多少进行重写,即当aof文件增长到一定大小的时候Redis能够调用bgrewriteaof对日志文件进行重写,如果之前没有重写,则以启动时的aof文件大小为依据。当前AOF文件大小是上次日志重写得到AOF文件大小的二倍(设置为100)时,自动启动新的日志重写过程。如果将百分比指定为0,则表示关闭该功能。

Redis启动时会自动读取RDB快照文件,将数据从硬盘载入到内存,根据数量的不同,这个过程持续的时间也不尽相同,通常来讲,一个记录1000万个字符串类型键,大小为1GB的快照文件载入到内存需要20-30秒的时间。

auto-aof-rewrite-min-size:设置允许重写的最小aof文件大小,避免了达到约定百分比但尺寸仍然很小的情况还要重写

示例

appendfsync:aof持久化策略的配置,no表示不执行fsync,由操作系统保证数据同步到磁盘(30秒每次,数据放在Page
Cache中),速度最快,但是最不安全。always表示每次写入都执行fsync,以保证数据同步到磁盘。everysec表示每秒执行一次fsync,可能会导致丢失这1s数据。dis-persistence-demystified.html,如果不确定,选择”everysec”。

下面演示RDB方式持久化,首先使用配置有如下快照规则:

RDB载入的速度要比AOF载入的快,当redis启动时,如果rdb持久化和aof持久化都打开了,那么程序会优先使用aof方式来恢复数据集,因为aof方式所保存的数据通常是最完整的。如果aof文件丢失了,则启动之后数据库内容为空。

save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
dir ./

注意:如果想把正在运行的redis数据库,从RDB切换到AOF,建议先使用动态切换方式,再修改配置文件,重启数据库。(不能直接修改配置文件,重启数据库,否则数据库中数据就为空了,因为加载的时候找不到aof文件,服务器就认为数据为空。)

启动Redis服务:

澳门新葡亰赌995577 3

然后通过客户端设置一个键值:

澳门新葡亰赌995577 4

现在强行kill Redis服务,执行shutdown命令:

澳门新葡亰赌995577 5

澳门新葡亰赌995577 6

现在到D:\Redis_x64_321\目录看,目录下出现了Redis的快照文件dump.rdb:

澳门新葡亰赌995577 7

现在重新启动Redis,然后再用客户端连接,检查之前设置的key是否还存在:

澳门新葡亰赌995577 8

可以发现,之前设置的key在Redis重启之后又通过快照文件dump.rdb恢复了。

2、AOF方式

在使用Redis存储非临时数据时,一般都需要打开AOF持久化来降低进程终止导致的数据丢失,AOF可以将Redis执行的每一条写命令追加到硬盘文件中,这一过程显然会降低Redis的性能,但是大部分情况下这个影响是可以接受的,另外,使用较快的硬盘能提高AOF的性能。

澳门新葡亰赌995577,开启AOF

默认情况下,Redis没有开启AOF(append only
file)持久化功能,可以通过在配置文件中作如下配置启用:

澳门新葡亰赌995577 9

开启之后,Redis每执行一条写命令就会将该命令写入硬盘中的AOF文件。AOF文件保存路径和RDB文件路径是一致的,都是通过dir参数配置,默认文件名是:appendonly.aof,可以通过配置appendonlyfilename参数修改,例如:

澳门新葡亰赌995577 10

AOF持久化的实现

AOF以纯文本的形式记录了Redis执行的写命令,例如在开启AOF持久化的情况下执行如下命令: