1. 程式人生 > >Redis的RDB和AOF

Redis的RDB和AOF

copy redis tar too 重寫 過程 rand pen 127.0.0.1

1.數據快照RDB

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