Redis持久化

redis學習筆記——RDB和AOF持久化一

 

因爲AOF文件的更新頻率通常比RDB文件的更新頻率高,所以如果服務器開啓了AOF持久化功能,那麼服務器會優先使用AOF文件來還原數據庫狀態。只有在AOF持久化功能處於關閉狀態時,服務器纔會使用RDB文件來還原數據庫狀態。

 

redis持久化:

 

兩種方式:rdb(redis database)和aof(append of file)

 

RDB:

在指定時間間隔內,將內存中的數據作爲一個快照文件(snapshot)寫入到磁盤,讀取的時候也是直接讀取snapshot文件到內存中

 

①持久化過程:redis單獨創建(fork)一個進程來持久化,會先將數據寫入臨時文件中,待上次持久化結束後,會將該臨時文件替換上次持久化文件,比aof高效,但是最後一次數據可能會丟失

②Fork:在linux中,fork()會產生一個跟主進程一樣的子進程,出於效率考慮,主進程和子進程會公用一段物理內存,當發生改變的時候,纔會把主進程“”寫時複製”一份給子進程

③Redis備份的文件:在redis.conf中設置,dbfilename默認爲:dump.rdb

 

Redis提供了save和bgsave兩個命令來生成RDB文件(即將內存數據寫入RDB文件中),執行成功後我們在磁盤中找到該RDB文件(dump.rdb)

兩個Redis命令可以用於生成RDB文件,一個是SAVE,另一個是BGSAVE

 

兩者區別:

SAVE命令會阻塞Redis服務器進程,直到RDB文件創建完畢爲止,在服務器進程阻塞期間,服務器不能處理任何命令請求;

BGSAVE命令會派生出一個子進程,然後由子進程負責創建RDB文件,服務器進程(父進程)繼續處理命令請求;

 

創建RDB文件的實際工作由rdb.c/rdbSave函數完成,SAVE命令和BGSAVE命令會以不同的方式調用這個函數

 

手動快照:

如果沒有觸發自動快照,可以對redis進行手動快照操作,SAVE和BGSAVE都可以執行手動快照,兩個命令的區別是前者是由主進程進行快照操作,會阻塞其他請求;而後者是通過fork子進程進行快照操作

 

注意:

由於redis使用fork來複制一份當前進程,那麼子進程就會佔有和主進程一樣的內存資源,比如說主進程8G內存,那麼在備份的時候必須保證有16G內存,要不然會啓用虛擬內存,性能非常差。

 

Redis的持久化-RDB

Redis的持久化-AOF

 

RDB文件中存放的是二進制數據

 

④ Rdb保存策略:

900s 1 file change

300s 10file change

60s 10000file change


 
 

⑤Rdb的備份:

config get dir 得到備份的文件夾

複製備份文件

 

⑥Rdb恢復:

關閉redis

將備份文件複製到工作目錄下

啓動redis,自動加載

 

 

AOF :

 以日誌形式記錄每個寫操作,啓動時通過日誌恢復操作

 

開啓AOF:默認不開啓,進入redis.conf找到appendonly yes打開

修復AOF:redis-check-aof –fix appendonly.aof

同步頻率:每秒記錄一次,如果宕機該秒記可能失效

 

Rewrite:bgrewrite  aof 因爲日誌是追加方式,文件會越來越大,當超過了設置的閾值時,日誌文件會壓縮,保留僅可以恢復的日誌

 

AOF重寫

重寫是爲了解決AOF文件越來越大的問題,所以需要將他的體積縮小。

 

AOF文件重寫的實現

首先從數據庫中讀取鍵現在的值,然後用一條命令去記錄鍵值對,代替之前記錄這個鍵值對的多條命令,這就是AOF重寫功能的實現原理

 

如:

redis> SADD animals "Cat"            

   // {"Cat"}

(integer) 1

redis> SADD animals "Dog" "Panda" "Tiger"    // {"Cat", "Dog", "Panda", "Tiger"}

(integer) 3

redis> SREM animals "Cat"                    // {"Dog", "Panda", "Tiger"}

(integer) 1

redis> SADD animals "Lion" "Cat"             // {"Dog", "Panda", "Tiger", 

(integer) 2                                     "Lion", "Cat"}

 

可以用:

SADD animals"Dog""Panda""Tiger""Lion""Cat" 命令代替。

 

aof的重寫是也是放在子程序中進行。不過,使用子進程也有一個問題需要解決,因爲子進程在進行AOF重寫期間,服務器進程還需要繼續處理命令請求,而新的命令可能會對現有的數據庫狀態進行修改,從而使得服務器當前的數據庫狀態和重寫後的AOF文件所保存的數據庫狀態不一致。

 

爲了解決這種數據不一致問題,Redis服務器設置了一個AOF重寫緩衝區這個緩衝區在服務器創建子進程之後開始使用,當Redis服務器執行完一個寫命令之後,它會同時將這個寫命令發送給AOF緩衝區和AOF重寫緩衝區,如圖所示:



 

這也就是說,在子進程執行AOF重寫期間,服務器進程需要執行以下三個工作:

1)執行客戶端發來的命令;

2)將執行後的寫命令追加到AOF緩衝區;

3)將執行後的寫命令追加到AOF重寫緩衝區。

 

這樣一來可以保證:

a、AOF緩衝區的內容會定期被寫入和同步到AOF文件,對現有AOF文件的處理工作會如常進行。

b、從創建子進程開始,服務器執行的所有寫命令都會被記錄到AOF重寫緩衝區裏面。

 

當子進程完成AOF重寫工作之後,它會向父進程發送一個信號,父進程在接到該信號之後,會調用一個信號處理函數,並執行以下工作:

 

1)將AOF重寫緩衝區中的所有內容寫入到新AOF文件中,這時新AOF文件所保存的數據庫狀態將和服務器當前的數據庫狀態一致。

2)對新的AOF文件進行改名,原子地(atomic)覆蓋現有的AOF文件,完成新舊兩個AOF文件的替換。

 

這個信號處理函數執行完畢之後,父進程就可以繼續像往常一樣接受命令請求了。

 

注意:

在整個AOF後臺重寫過程中,只有信號處理函數執行時會對服務器進程(父進程)造成阻塞,在其他時候,AOF後臺重寫都不會阻塞父進程,這將AOF重寫對服務器性能造成的影響降到了最低。

 

=================================================================

RDB優點:

節省磁盤空間

恢復速度快

 

缺點:

數據太大時,比較消耗性能

一段時間保存一次快照,宕機時最後一次可能沒有保存

 

AOF優點:

備份機制更加穩健

可讀的日誌文件,通過aof恢復更加穩健,可以處理失誤

 

缺點:

比RDB更佔磁盤

備份速度較慢

每次都同步日誌,有性能壓力

 

RDB和AOF哪個好

官方推薦都啓用

對數據不敏感,單獨用RDB

不建議單獨使用AOF

若作爲純緩存使用,可以都不開啓

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章