Redis的RDB和AOF
1.1原理
(1)RDB是將某一時刻的數據持久化到磁盤中,是一種快照的方式。
(2)redis在進行數據持久化的過程中,會先將數據寫入到一個臨時文件中,待持久化過程都結束了,才會用這個臨時文件替換上次持久化好的文件。正是這種特性,讓我們可以隨時來進行備份,及時redis處於運行狀態;
(3)對於RDB方式,redis會單獨創建(fork)一個子進程來進行持久化,而主進程是不會進行任何IO操作的,這樣就確保了redis極高的性能。
(4)如果需要進行大規模數據的恢復,且對於數據恢復的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。
如果你對數據的完整性非常敏感,那麽RDB方式就不太適合你,因為即使你每5分鐘都持久化一次,當redis故障時,仍然會有近5分鐘的數據丟失。所以,redis還提供了另一種持久化方式,那就是AOF。
1.2生成快照的幾種方法
手動觸發:
(1)save命令用於創建當前數據庫的備份,該命令將在 redis 安裝目錄dir下創建dump.rdb文件;
如果需要恢復數據,只需將備份文件dump.rdb移動到 redis 安裝目錄並啟動服務即可。獲取redis目錄可以使用 config get dir命令
(2) bgsave在後臺執行;
(3)shutdown save,關閉服務的時候,shutdown有兩個選項,nosave|save,如果不加,默認是save;
自動觸發:
(4)配置文件redis.conf中的設置:
save 900 1
save 300 10
save 60 10000
dbfilename dump.rdb
1.3 使用rdb文件進行還原測試
註意:還原的時候需要關閉aof的功能,否則redis在啟動的時候會加載appendonly.aof這個日誌文件,這樣恢復的就不是dump.rdb的內容了,而是應用的aof日誌
#使用redis-benchmark加載測試數據,並關閉aof:
src/redis-benchmark -h 127.0.0.1 -p 6379 -n 200000 -c 20 -d 4 -k 1 --csv > redis_benchmart_$(date +%Y%m%d).log 2>&1
[root@sht-sgmhadoopcm-01 redis]# src/redis-cli
127.0.0.1:6379> config get dir
1) "dir"
2) "/usr/local/redis"
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "no"
127.0.0.1:6379> keys *
1) "key1"
2) "key2"
3) "key:__rand_int__"
4) "mylist"
5) "counter:__rand_int__"
127.0.0.1:6379> shutdown save
[root@sht-sgmhadoopcm-01 redis]# mv dump.rdb dump.rdb.bak
[root@sht-sgmhadoopcm-01 redis]# src/redis-server redis.conf
[root@sht-sgmhadoopcm-01 redis]# src/redis-cli
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> shutdown nosave
把備份的rdb文件放在指定位置,並重啟redis,這樣數據又恢復了
[root@sht-sgmhadoopcm-01 redis]# mv dump.rdb.bak dump.rdb
[root@sht-sgmhadoopcm-01 redis]# src/redis-server redis.conf
[root@sht-sgmhadoopcm-01 redis]# src/redis-cli
127.0.0.1:6379> keys *
1) "key:__rand_int__"
2) "mylist"
3) "key2"
4) "key1"
5) "counter:__rand_int__"
2.AOF(append only file)
2.1 AOF
(1)即只允許追加,不允許更改的文件
開啟方法:appendonly yes
AOF方式是將執行過的寫指令記錄下來,在數據恢復時按照從前到後的順序再將指令都執行一遍;
同樣數據集的情況下,AOF文件要比RDB文件的體積大。而且,AOF方式的恢復速度也要慢於RDB方式。
我們通過配置redis.conf中的appendonly yes就可以打開AOF功能。如果有寫操作(如SET等),redis就會被追加到AOF文件的末尾。
默認的AOF持久化策略是每秒鐘fsync一次(fsync是指把緩存中的寫指令記錄到磁盤中),因為在這種情況下,redis仍然可以保持很好的處理性能,即使redis故障,也只會丟失最近1秒鐘的數據。
(2)如果在追加日誌時,恰好遇到磁盤空間滿、inode滿或斷電等情況導致日誌寫入不完整,redis提供了redis-check-aof工具,可以用來進行日誌修復:
Make a backup copy of your AOF file.
Fix the original file using the redis-check-aof tool that ships with Redis: $ redis-check-aof --fix appendonly.aof
Optionally use diff -u to check what is the difference between two files.
Restart the server with the fixed file.
(3)通過appendonly.aof文件進行還原測試
127.0.0.1:6379> config get appendonly
1) "appendonly"
2) "yes"
127.0.0.1:6379> mset key1 1 key2 2 key3 3
OK
127.0.0.1:6379> keys *
1) "key3"
2) "key1"
3) "key2"
[root@sht-sgmhadoopcm-01 redis]# cp appendonly.aof appendonly.aof.bak
127.0.0.1:6379> flushall
OK
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379> shutdown
[root@sht-sgmhadoopcm-01 redis]# rm -rf appendonly.aof
[root@sht-sgmhadoopcm-01 redis]# mv appendonly.aof.bak appendonly.aof
[root@sht-sgmhadoopcm-01 redis]# src/redis-server redis.conf
[root@sht-sgmhadoopcm-01 redis]# src/redis-cli
127.0.0.1:6379> keys *
1) "key1"
2) "key2"
3) "key3"
2.2 aof文件的rewrite
(1)rewrite原理
因為采用了追加方式,如果不做任何處理的話,AOF文件會變得越來越大,為此,redis提供了AOF文件重寫(rewrite)機制,即當AOF文件的大小超過所設定的閾值時,redis就會啟動AOF文件的內容壓縮,只保留可以恢復數據的最小指令集。假如我們調用了100次INCR指令,在AOF文件中就要存儲100條指令,但這明顯是很低效的,完全可以把這100條指令合並成一條SET指令,這就是重寫機制的原理。
在進行AOF重寫時,仍然是采用先寫臨時文件,全部完成後再替換的流程,所以斷電、磁盤滿等問題都不會影響AOF文件的可用性。
AOF方式的另一個好處,我們通過一個“場景再現”來說明。某同學在操作redis時,不小心執行了flushall,導致redis內存中的數據全部被清空了,只要redis配置了AOF持久化方式,且AOF文件還沒有被重寫(rewrite),我們就可以用最快的速度暫停redis並編輯AOF文件,將最後一行的FLUSHALL命令刪除,然後重啟redis,就可以恢復redis的所有數據到FLUSHALL之前的狀態了。但是如果AOF文件已經被重寫了,那就無法通過這種方法來恢復數據了。
(2)觸發rewrite的方法
第一種方法:使用bgrewriteaof命令手動觸發;
第二種方法:由配置文件控制
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
比如上邊的參數設置的含義:當appendonly.aof為小於64M時,不會觸發rewrite,當文件大64M,增長率達到100%,即為128M時,觸發一次rewrite,這個時候redis記住文件rewrite之後的大小,假如為80M,只有等到文件再次漲到160M後,才會觸發下一次,依次類推
3 總結:
官方推薦同時開啟這兩種備份策略,確保數據更加安全;
如果你的業務可以接受一定數據的丟失,更註重性能,可以只開啟RDB;
如果只把redis作為一個緩存來用,則不需要開啟RDB和AOF;
參考鏈接
https://redis.io/topics/persistence
Redis的RDB和AOF