redis的持久化主要提供了2種方法,快照(snapshot)方法和AOF(append only)方法,作實驗試一下這2種方法。redis
快照方法是把redis內存中的數據在隔一段時間以後,fork一個子進程,在子進程中將內存中的數據寫入存儲。固然這種模式下,若是系統異常退出會出現數據的丟失,更嚴重的是由於要fork子進程,內存的消耗會在短期內忽然倍增。數據庫
下面作實驗來看一下,先從啓動一個空的redis數據庫開始oracle
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中修改配置app
# 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有關,默認配置以下,我沒改ui
save 900 1 save 300 10 save 60 10000
表示:900秒內,至少有1個key發生變更,那麼就寫入;以此類推後2條。我剛纔的實驗中,只修改了1個數據,那麼我就須要在900秒內模擬系統異常退出,不然redis仍是會寫入。spa
再來看一下AOF持久化方法,AOF的作法是,將每一次數據的變更寫入aof文件,而後相似快照產生的方法,fork一個進程來作,這樣就不會丟失數據,這個有點相似與oracle的redo log的原理,可是比較弱。使用AOF以後,快照方法就再也不適用,一樣,rdb文件中的數據也不會再被讀入,而是徹底用aof文件代替。redis還對aof作了一些優化,好比aof rewrite,若是一個key有屢次寫入,那麼只取最後一次寫入。作實驗來看一下,AOF如何作到不丟失數據,首先,在配置文件中啓用AOF,默認是不啓用的code
# comment by valleylord, origin setting changes # rdbcompression yes appendonly yes # The name of the append only file (default: "appendonly.aof") appendfilename appendonly.aof
實驗的過程以下server
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寫會存儲的作法仍是簡單了很多。blog