redis支持兩種持久化方式,一種是RDB,一種是AOF。redis
RDB是根據指定的規則定時將內存中的數據備份到硬盤上,AOF是在每次執行命令後命令自己記錄下來,因此RDB的備份文件是一個二進制文件,而AOF的備份文件是一個文本文件。數據庫
RDB的備份是經過快照來完成的,當符合設定的條件時redis會將內存中的全部數據自動生成一份副本保存到硬盤上,這個保存的過程就是快照。安全
這個條件在配置文件中指定,由兩個參數所定義:時間窗口M和改動的鍵個數N,每當時間M內改動的鍵個數大於N時,則觸發快照備份。服務器
能夠同時存在多個快照條件,條件之間是或的關係,也就是說只要有一個條件被觸發就會執行快照備份。多線程
save 900 1 : 在15分鐘內有至少一個鍵被修改則觸發。
save 300 10 : 在5分鐘內至少有10個鍵被修改則觸發。
sae 60 10000 : 在一分鐘內有10000個鍵被修改則觸發。app
save命令會讓redis同步地執行快照操做,在快照執行的時候會阻塞全部來自客戶端的請求,當數據庫中的數據比較多時備份時間可能就比較長,就會致使服務器長時間無響應,因此此項在生產環境應該慎用。異步
須要手動執行快照備份的話應該使用bgsave命令,bgsave命令能夠在後臺異步的執行備份操做,在備份快照的同時服務器仍然可以相應客戶端的請求。函數
既然bgsave那麼好,爲毛還要save呢?
save能夠一直阻塞等到結果,可是由於bgsave是多線程,在執行bgsave的時候只是啓動一個線程去備份,咱們並不能肯定備份到底有沒有成功呢?當指定bgsave的時候老是返回OK,這個OK表示的是開始執行快照操做並非快照操做執行成功,要想知道快照是否執行成功,能夠經過lastsave命令獲取最近一次成功執行快照的時間,返回結果是一個unix時間戳。優化
當執行flushall的時候redis會清空當前倉庫的全部數據,只要自動快照條件不爲空的話在清空以前就要執行一次備份,當沒有定義快照觸發條件的時候執行flushall不會執行備份。spa
當設置了主從模式時,redis會在初始化時自動進行快照。
redis默認會將快照放到當前進程工做目錄的dump.db文件中,能夠經過配置dir和dbfilename兩個參數來指定要保存到的路徑和文件名。
爲了節省空間,RDB文件是通過壓縮的,在硬盤上的佔用空間會小於在內存中的佔用空間,能夠經過rdbcompression參數來禁用掉壓縮(可節省些許cpu佔用吧)
rdb快照備份的過程(copy-on-write):
1. redis用fork函數複製一份當前進程的副本。
2. 父進程繼續接受客戶端發來的命令,子進程開始將內存中的數據寫到硬盤的臨時文件。
3. 當子進程備份完的時候將子進程和父進程的數據合併。
(沒看過源代碼,上面抄來的... = = )
注: copy-on-write是一種比較經常使用的備份策略。
aof通常用於對數據丟失容忍度不高的狀況下,用於對數據保存要求較高的場景。
默認狀況下redis是沒有開啓aof的,使用appendonly來開啓(appendonly yes):
能夠經過appendfilename來指定aof文件的名字,默認的名字是【appendonly.aof】:
aof文件以純文本的形式記錄了redis執行的命令,它只是傻傻的把執行過的命令往aof文件中添加並不知道添加的是個什麼,這樣就可能存在一個問題,好比下面連着的兩條命令:
set foo bar
set foo baar
在aof文件中會忠實的記錄下整個改變的過程,而不是機智的只存儲一個set foo baar。
這樣子的話aof文件中就可能會存在冗餘命令,因此能夠設定一個觸發條件,設定每到必定條件時就讓redis優化aof文件,優化aof文件的策略是與以前aof的內容無關,而是跟當前內存中的數據有關(在內存中都已經不存在的命令沒有存在必要了,對於已經存在的只保留最後一次的操做就能夠啦),進行設定的參數:
auto-aof-rewrite-percentage : 當前的aof文件超過上一次重寫時大小的百分之多少時再次進行重寫,若是以前沒有重寫過,則以啓動時的aof文件大小爲依據。
auto-aof-rewrite-min-size : 限制容許重寫aof文件的最小的大小,好比當aof文件很小的時候有冗餘也不要緊的,咱們就不要再去抽出資源來重寫它啦,這個是aof文件小於64M則不會進行重寫。
每次同步數據庫的內容時redis都會將命令記錄到aof文件中,可是事實上咱們都知道硬盤是有一個寫緩衝區的,要寫的東西並不會當即就寫到硬盤上而是如今硬盤的緩衝區內待一下子,等到攢夠了人頭再「拼車」一塊兒寫入硬盤,在默認狀況下操做系統每30秒會執行一次同步操做,會將硬盤緩衝區的內容真正的寫入到硬盤,可是在這30秒內若是發生了什麼人力不可抗拒因素啥的這數據但是就丟了哇,咱們用aof就是爲了儘可能不丟失數據,因此有一個選項appendfsync用來指定同步的策略:
always : 表示每次都會寫入硬盤,這是最安全也是最慢的方式(請確保丫硬盤夠給力....)。
everysec : 每秒同步一次(默認)
no : 不會主動進行同步,讓操做系統看着辦吧,操做系統默認的是每30秒將硬盤緩衝區內的數據同步到的硬盤一次。
RDB和AOF能夠同時配置的,當同時開啓的時候啓動的時候redis會加載AOF文件,由於一般狀況下AOF持久化保存的數據更完整一些。
參考資料:
1. 《redis入門指南》 第二版