Redis是一個支持持久化的內存數(shù)據(jù)庫,通過持久化機制把內存中的數(shù)據(jù)同步到硬盤文件來保證數(shù)據(jù)持久化。當Redis重啟后通過把硬盤文件重新加載到內存,就能達到恢復數(shù)據(jù)的目的。
RDB
RDB是Redis默認的持久化方式。按照一定的時間周期策略把內存的數(shù)據(jù)以快照的形式保存到硬盤的二進制文件。即Snapshot快照存儲,對應產(chǎn)生的數(shù)據(jù)文件為dump.rdb,通過配置文件中的save參數(shù)來定義快照的周期。
- # 快照的文件名
- dbfilename dump.rdb
- # 存放快照的目錄
- dir /var/lib/redis
- # 在進行鏡像備份時,是否進行壓縮。
- # yes:壓縮,但是需要一些cpu的消耗。
- # no:不壓縮,需要更多的磁盤空間。
- rdbcompression yes
- #900秒后且至少1個key發(fā)生變化時創(chuàng)建快照
- save 900 1
- #300秒后且至少10個key發(fā)生變化時創(chuàng)建快照
- save 300 10
- #60秒后且至少10000個key發(fā)生變化時創(chuàng)建快照
- save 60 10000
一旦數(shù)據(jù)庫出現(xiàn)問題,那么我們的RDB文件中保存的數(shù)據(jù)并不是全新的,從上次RDB文件生成到Redis停機這段時間的數(shù)據(jù)全部丟掉了。例如,每隔5分鐘或者更長的時間來創(chuàng)建一次快照,Redis停止工作時(例如意外斷電)就可能丟失最近幾分鐘的數(shù)據(jù)。
AOF
Redis會將每一個收到的寫命令都通過Write函數(shù)追加到文件最后,類似于MySQL的binlog。當Redis重啟是會通過重新執(zhí)行文件中保存的寫命令來在內存中重建整個數(shù)據(jù)庫的內容。
- # 是否開啟AOF,默認關閉(no)
- appendonly yes
由于Linux會把對文件的寫入操作通過buffer緩沖,因此Linux可能不是立即寫入到文件,有對視數(shù)據(jù)的風險。Redis有三種不同的fsync策略供選擇:no fsync at all、 fsync every second、 fsync at every query。默認為fsync every second此時的寫性能仍然很好,且最壞的情況下可能丟失一秒鐘的寫操作。
- # Redis支持三種不同的刷寫模式:
- #每次收到寫命令就立即強制寫入磁盤,是最有保證的完全的持久化,但速度也是最慢的,一般不推薦使用。
- # appendfsync always
- #每秒鐘強制寫入磁盤一次,在性能和持久化方面做了很好的折中,是受推薦的方式。
- appendfsync everysec
- #完全依賴OS的寫入,一般為30秒左右一次,性能最好但是持久化最沒有保證,不被推薦。
- # appendfsync no
AOF帶來了另一個問題,持久化文件會變得越來越大。比如,我們調用INCR test命令100次,文件中就必須保存全部的100條命令,但其實99條都是多余的。因為要恢復數(shù)據(jù)庫的狀態(tài)其實文件中保存一條SET test 100就夠了。為了合并重寫AOF的持久化文件,Redis提供了bgrewriteaof命令。收到此命令后,Redis將使用與快照類似的方式將內存中的數(shù)據(jù)以命令的方式保存到臨時文件中,最后替換原來的文件,以此來實現(xiàn)控制AOF文件的合并重寫。由于是模擬快照的過程,因此在重寫AOF文件時并沒有讀取舊的AOF文件,而是將整個內存中的數(shù)據(jù)庫內容用命令的方式重寫了一個新的AOF文件。
- # AOF文件名
- appendfilename appendonly.aof
- #當進程中BGSAVE或BGREWRITEAOF命令正在執(zhí)行時不阻止主進程中的fsync()調用(默認為no,當存在延遲問題時需調整為yes)
- no-appendfsync-on-rewrite no
- #當AOF增長率為100%且達到了64mb時開始自動重寫AOF
- auto-aof-rewrite-percentage 100
- auto-aof-rewrite-min-size 64mb