因爲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內存,要不然會啓用虛擬內存,性能非常差。
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
若作爲純緩存使用,可以都不開啓