Redis支持两种方式的持久化,一种是RDB方式,一种是AOF方式。可以单独使用其中一种或将二者结合使用。
RDB方式的持久化是通过快照(snapshotting )完成的,当符合一定条件时Redis会自动将内存中的所有数据进行快照并存储在硬盘上。进行快照的条件可以由用户在配置文件中自定义,由两个参数构成:时间和改动的键的个数。当在指定的时间内被更改的键的个数大于指定的数值时就会进行快照。RDB是Redis默认采用的持久化方式,在配置文件中已经预置了3个条件:
save 900 1 save 300 10 save 60 10000
save参数指定了快照条件,可以存在多个条件,条件之间是“或”的关系。如上所说,save 900 1的意思是在15分钟(900秒钟)内有至少一个键被更改则进行快照。
如果想要禁用自动快照,只需要将所有的save参数删除即可。
Redis默认会将快照文件存储在当前目录的dump.rdb文件中,可以通过配置dir和dbfilename两个参数分别指定快照文件的存储路径和文件名。
在执行fork 的时候操作系统(类Unix 操作系统)会使用写时复制(copy-on-write)策略,即fork 函数发生的一刻父子进程共享同一内存数据,当父进程要更改其中某片数据时(如执行一个写命令),操作系统会将该片数据复制一份以保证子进程的数据不受影响,所以新的RDB文件存储的是执行fork 一刻的内存数据。
通过上述过程可以发现Redis在进行快照的过程中不会修改RDB文件,只有快照结束后才会将旧的文件替换成新的,也就是说任何时候RDB文件都是完整的。这使得我们可以通过定时备份RDB文件来实现Redis数据库备份。RDB文件是经过压缩(可以配置rdbcompression 参数以禁用压缩节省CPU占用)的二进制格式,所以占用的空间会小于内存中的数据大小,更加利于传输。
Redis启动后会读取RDB快照文件,将数据从硬盘载入到内存。根据数据量大小与结构和服务器性能不同,这个时间也不同。
通常将一个记录一千万个字符串类型键、大小为1GB的快照文件载入到内存中需要花费20~30秒钟。
通过RDB方式实现持久化,一旦Redis异常退出,就会丢失最后一次快照以后更改的所有数据。这就需要开发者根据具体的应用场合,通过组合设置自动快照条件的方式来将可能发生的数据损失控制在能够接受的范围。如果数据很重要以至于无法承受任何损失,则可以考虑使用AOF方式进行持久化。
默认情况下Redis没有开启AOF(append only file)方式的持久化,可以通过appendonly 参数开启:
appendonly yes
append file name appendonly.aof
SET foo 1 SET foo 2 SET foo 3 GET foo
*2 $6 <strong>SELECT</strong> $1 <strong>0</strong> *3 $3 <strong>set</strong> $3 <strong>foo</strong> $1 <strong>1</strong> *3 $3 <strong>set</strong> $3 <strong>foo</strong> $1 <strong>2</strong> *3 $3 <strong>set</strong> $3 <strong>foo</strong> $1 <strong>3</strong>
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
auto-aof-rewrite-percentage参数的意义是当目前的AOF文件大小超过上一次重写时的AOF文件大小的百分之多少时会再次进行重写,如果之前没有重写过,则以启动时的AOF文件大小为依据。
auto-aof-rewrite-min-size参数限制了允许重写的最小AOF文件大小,通常在AOF文件很小的情况下即使其中有很多冗余的命令我们也并不太关心。
除了让Redis自动执行重写外,我们还可以主动使用BGREWRI TEAOF命令手动执行AOF重写。
*2 $6 <strong>SELECT</strong> $1 <strong>0</strong> *3 $3 <strong>SET</strong> $3 <strong>foo</strong> $1 <strong>3</strong>
可见冗余的命令已经被删除了。重写的过程只和内存中的数据有关,和之前的AOF文件无关,这与RDB很相似,只不过二者的文件格式完全不同。
需要注意的是虽然每次执行更改数据库内容的操作时,AOF都会将命令记录在AOF文件中,但是事实上,由于操作系统的缓存机制,数据并没有真正地写入硬盘,而是进入了系统的硬盘缓存。在默认情况下系统每30秒会执行一次同步操作,以便将硬盘缓存中的内容真正地写入硬盘,在这30秒的过程中如果系统异常退出则会导致硬盘缓存中的数据丢失。一般来讲启用AOF持久化的应用都无法容忍这样的损失,这就需要Redis在写入AOF文件后主动要求系统将缓存内容同步到硬盘中。
在Redis中我们可以通过appendfsync参数设置同步的时机:
# appendfsync always appendfsync everysec # appendfsync no
默认情况下Redis采用everysec 规则,即每秒执行一次同步操作。always表示每次执行写入都会执行同步,这是最安全也是最慢的方式。no表示不主动进行同步操作,而是完全交由操作系统来做(即每30秒一次),这是最快但最不安全的方式。一般情况下使用默认值everysec就足够了,既兼顾了性能又保证了安全。
原文地址:http://blog.csdn.net/wtyvhreal/article/details/42916503