redis持久化的快照(snapshot)方法和AOF方法

redis的持久化主要提供了2种方法,快照(snapshot)方法和AOF(append only)方法,做实验试一下这2种方法。

快照方法是把redis内存中的数据在隔一段时间之后,fork一个子进程,在子进程中将内存中的数据写入存储。当然这种模式下,如果系统异常退出会出现数据的丢失,更严重的是因为要fork子进程,内存的消耗会在短时间内突然倍增。

下面做实验来看一下,先从启动一个空的redis数据库开始

xxxx@xxxx-computer:~$ ps -ef | grep redis
xxxx     5071  4168  0 10:12 pts/0    00:00:00 grep --color=auto redis
xxxx@xxxx-computer:~$ sudo ls -l /var/lib/redis/dump.rdb 
-rw-r--r-- 1 root root 18  2月 15 10:11 /var/lib/redis/dump.rdb
xxxx@xxxx-computer:~$ sudo cat /var/lib/redis/dump.rdb
REDIS0006�ܳC�Z��Vxxxx@xxxx-computer:~$ 
xxxx@xxxx-computer:~$ sudo redis-server /etc/redis/redis.conf 
xxxx@xxxx-computer:~$ redis-cli -h localhost -p 6379
redis localhost:6379> keys *
(empty list or set)
redis localhost:6379> set str1 abcdef
OK
redis localhost:6379> set num1 123
OK
redis localhost:6379> keys *
1) "num1"
2) "str1"
redis localhost:6379> quit
xxxx@xxxx-computer:~$ redis-cli -h localhost -p 6379 shutdown
xxxx@xxxx-computer:~$ sudo ls -l /var/lib/redis/dump.rdb 
-rw-r--r-- 1 root root 41  2月 15 10:15 /var/lib/redis/dump.rdb
xxxx@xxxx-computer:~$ sudo cat /var/lib/redis/dump.rdb
REDIS0006�num1�{str1abcdef�O�j'�xxxx@xxxx-computer:~$ 
xxxx@xxxx-computer:~$ clear

在set数据之后,用正常的方式shutdown redis,redis-cli shutdown,完成之后,在redis的dump文件中会看到操作中set的数据,如果你看到的是乱码,那么应该是你的redis启用了rdb压缩(rdbcompression),默认这一项是启用的,取消就好。在redis.conf中修改配置

# comment by valleylord, origin setting changes
# rdbcompression yes
rdbcompression no

如果是redis非正常退出的话,这个在实验中可以用kill来模拟,如之前所说,可能会出现数据丢失,实验步骤如下

xxxx@xxxx-computer:~$ ps -ef |grep redis
xxxx     5192  4168  0 10:20 pts/0    00:00:00 grep --color=auto redis
xxxx@xxxx-computer:~$ sudo ls -l /var/lib/redis/dump.rdb 
-rw-r--r-- 1 root root 41  2月 15 10:15 /var/lib/redis/dump.rdb
xxxx@xxxx-computer:~$ sudo cat /var/lib/redis/dump.rdb
REDIS0006�num1�{str1abcdef�O�j'�xxxx@xxxx-computer:~$ 
xxxx@xxxx-computer:~$ sudo redis-server /etc/redis/redis.conf 
xxxx@xxxx-computer:~$ redis-cli -h localhost -p 6379
redis localhost:6379> keys *
1) "str1"
2) "num1"
redis localhost:6379> set str2 wxyz
OK
redis localhost:6379> keys *
1) "str1"
2) "str2"
3) "num1"
redis localhost:6379> get str2
"wxyz"
redis localhost:6379> quit
xxxx@xxxx-computer:~$ sudo ls -l /var/lib/redis/dump.rdb 
-rw-r--r-- 1 root root 41  2月 15 10:15 /var/lib/redis/dump.rdb
xxxx@xxxx-computer:~$ sudo killall -9 redis-server
xxxx@xxxx-computer:~$ sudo ls -l /var/lib/redis/dump.rdb 
-rw-r--r-- 1 root root 41  2月 15 10:15 /var/lib/redis/dump.rdb
xxxx@xxxx-computer:~$ sudo cat /var/lib/redis/dump.rdb
REDIS0006�num1�{str1abcdef�O�j'�xxxx@xxxx-computer:~$ 
xxxx@xxxx-computer:~$ ps -ef| grep redis
xxxx     5236  4168  0 10:23 pts/0    00:00:00 grep --color=auto redis
xxxx@xxxx-computer:~$ sudo redis-server /etc/redis/redis.conf 
xxxx@xxxx-computer:~$ redis-cli -h localhost -p 6379
redis localhost:6379> get str2
(nil)
redis localhost:6379> keys *
1) "num1"
2) "str1"
redis localhost:6379> quit

实验中,继续前一个实验的操作,又设置了str2这个key,然后快速的退出,并用kill杀掉redis-server进程,再次启动发现数据str2丢失。实验的效果与配置项save有关,默认配置如下,我没改

save 900 1
save 300 10
save 60 10000

表示:900秒内,至少有1个key发生变动,那么就写入;以此类推后2条。我刚才的实验中,只修改了1个数据,那么我就需要在900秒内模拟系统异常退出,否则redis还是会写入。

再来看一下AOF持久化方法,AOF的做法是,将每一次数据的变动写入aof文件,然后类似快照产生的方法,fork一个进程来做,这样就不会丢失数据,这个有点类似与oracle的redo log的原理,但是比较弱。使用AOF之后,快照方法就不再适用,同样,rdb文件中的数据也不会再被读入,而是完全用aof文件代替。redis还对aof做了一些优化,比如aof rewrite,如果一个key有多次写入,那么只取最后一次写入。做实验来看一下,AOF如何做到不丢失数据,首先,在配置文件中启用AOF,默认是不启用的

# comment by valleylord, origin setting changes
# rdbcompression yes
appendonly yes

# The name of the append only file (default: "appendonly.aof")
appendfilename appendonly.aof

实验的过程如下

xxxx@xxxx-computer:~$ ps -ef | grep redis
xxxx     6769  4168  0 15:26 pts/0    00:00:00 grep --color=auto redis
xxxx@xxxx-computer:~$ sudo redis-server /etc/redis/redis.conf 
xxxx@xxxx-computer:~$ redis-cli -h localhost -p 6379
redis localhost:6379> keys *
(empty list or set)
redis localhost:6379> set str2 xyz
OK
redis localhost:6379> set num2 98765
OK
redis localhost:6379> keys *
1) "str2"
2) "num2"
redis localhost:6379> quit
xxxx@xxxx-computer:~$ ls -l /var/lib/redis/appendonly.aof 
-rw-r--r-- 1 root root 89  2月 15 15:27 /var/lib/redis/appendonly.aof
xxxx@xxxx-computer:~$ sudo killall -9 redis-server
xxxx@xxxx-computer:~$ ps -ef | grep redis
xxxx     6854  4168  0 15:29 pts/0    00:00:00 grep --color=auto redis
xxxx@xxxx-computer:~$ sudo redis-server /etc/redis/redis.conf 
xxxx@xxxx-computer:~$ redis-cli -h localhost -p 6379
redis localhost:6379> get str2 
"xyz"
redis localhost:6379> get num2
"98765"
redis localhost:6379> quit
xxxx@xxxx-computer:~$ 

在写入数据之后立刻kill掉redis,模拟意外停止服务,然后重启redis,数据并未丢失。同时也可以看到,在改为AOF之后,第一次启服务的时候,之前设置的str1和num1均丢失了,应为改为AOF之后,系统不再从rdb中读数据。这个跟oracle定时将redo log写会存储的做法还是简单了不少。

posted @ 2014-02-16 09:08  valleylord  阅读(1438)  评论(0编辑  收藏  举报