redis提供了rdb持久化和aof持久化
rdb機制的優勢和策略
rdb持久化是指在指定的時間間隔內將記憶體中的資料集快照寫入磁碟。
也是預設的持久化方式,這種方式就是講記憶體中的資料以快照的方式寫入到二進位制檔案中,預設的檔案檔名為dump.rdb。
可以通過配置設定自動做快照持久化的方式。我們可以配置redis在n秒內如果超過m個key被修改就自動做快照,下面就是預設的快照儲存配置
s**e 900 1 //900秒內如果有超過乙個key被修改,則發起快照儲存
s**e 300 10 //300秒內如果超過10key被修改,則發起快照儲存
s**e 60 10000
rdb檔案儲存過程
redis 呼叫fork,現在有了子程序和父程序
父程序繼續處理client請求,子程序負責將記憶體內容寫入到臨時檔案。由於os寫時複製機制(copy on write) 父子程序會共享相同的物理頁面,當父程序處理寫請求時os會為父程序要修改的頁面建立副本,而不是共享頁面。所以子程序的位址空間的內資料是fork時刻的整個資料庫的乙個快照。
當子程序將快照寫入臨時檔案完畢後,用臨時檔案替換原來的快照檔案,然後子程序退出。
client 也可以使用s**e或者bgs**e命令通知redis做一次快照持久化。s**e操作是在主程序中儲存快照的,由於redis是用乙個主程序程來處理所有的client的請求,這種方式會阻塞所有的client請求,所以不推薦使用。
另外一點需要注意的是,每次快照持久化都是講記憶體中的資料完整的寫入到磁碟一次,並不是增量的只同步髒資料。如果資料量大的話,而且寫操作比較多,必然會引起大量的磁碟io操作,可能會嚴重影響效能。
優勢
一旦採用該方式,那麼你的整個redis資料庫將只包含乙個檔案,這樣非常方便進行備份。
方便遷移,我們可以很容易的將乙個rdb檔案遷移到其他的儲存介質上
rdb在恢復大資料集時的資料比aof恢復資料要快
rdb可以最大化redis效能:父程序在儲存rdb檔案時唯一需要做的是fork出乙個子程序,然後子程序會去處理接下來的所有儲存工作,父程序無需執行任何磁碟i/o操作
劣勢
如果你需要盡量避免在伺服器故障時丟失資料,那麼rdb不適合你。雖然redis允許你設定不同的儲存點來控制儲存rdb檔案的頻率,但是,應為rdb檔案需要儲存整個資料集的狀態,所以它並不是乙個輕鬆操作。假如我們至少5分鐘才會儲存一次資料(rdb檔案)。在這種情況下,一旦發生伺服器故障,你局有可能丟失幾分鐘的資料。
每次儲存rdb的時候,redis都要fork()出乙個子程序,並由子程序進行實際的持久化工作,在資料比較龐大的時候,fork可能會非常耗時,造成伺服器在毫秒內停止處理客戶端;如果資料集非常巨大,並且cpu實際非常緊張的話,這種耗時可能會長大整整一秒。
aof檔案儲存過程
當redis重啟時會通過重新執行檔案儲存的寫命令來在記憶體重建整個資料庫內容。當然由於os會在核心中快取write做的修改,所以可能不是立即寫在磁碟上。這樣aof方式持久化也還是有可能會丟失部分修改。不過我們可以通過配置檔案告訴redis我們想要通過fsync函式強制os寫入到磁碟的時機。有三種方式如下(預設是:每秒fsync一次)
aof的方式也同事帶來了另外乙個問題。持久化檔案會變的越來越大。例如我們呼叫 incr test 命令100次,檔案中必須儲存全部的100條命令,其實有99條是多餘的。因為要回覆資料庫的狀態其實檔案中儲存一條set test 100 就夠了。
為了壓縮aof的持久化檔案,redis 提供了bgrewriteaof命令。收到此命令redis將使用與快照類似的方式將記憶體中的資料以命令方式儲存到臨時檔案中,最後替換原來的檔案。具體過程如下
redis呼叫fork,現在有父子兩個程序
子程序根據記憶體中的資料庫快照,往臨時檔案中寫入重建資料庫狀態的命令
父程序繼續處理client請求,除了把寫命令寫入到原來的aof檔案中。同時把收到的寫命令快取起來。這樣就能保證如果子程序重寫失敗的話並不會出現問題。
當子程序把快照內容寫入以命令方式寫到臨時檔案中後,子程序發出訊號通知父程序,然後父程序把快取的寫命令也寫入到臨時檔案。
現在父程序可以使用臨時檔案替換老的aof檔案,並重命名,後面收到的寫命令也開始往新的aof檔案中追加。
需要注意的是重寫aof檔案的操作,並沒有讀取舊的aof檔案,而是講整個記憶體中的資料庫內容用命令的方式重寫了乙個新的aof檔案,這點和快照有點類似。
優勢1、使用aof持久化會讓redis變得非常耐用:你可以使用fsync策略,比如無fsync,每秒,每次執行寫入命令是fsync。aof的預設策略為每秒鐘fsync一次,在這種配置下,redis依然可以保持良好的效能,並且就算發生故障,也最多會丟失一秒鐘的資料
2、aof檔案是乙個只進行追加操作的日誌檔案,因此對aof檔案的寫入不需要進行seek,即使日誌因為某些原因而包含了未寫入的完整命令,redis-check-aof工具也可以輕鬆修復這種問題。
redis可以在aof檔案體積變得過大時,自動的在後台對aof進行重寫:重寫後的新的aof檔案包含了恢復當前資料集所需最小命令集合。整個重寫操作是絕對安全的,因為redsi在建立新的aof檔案時,會繼續將命令追加到先有的aof檔案裡面,即使重寫過程發生停機,現有的aof檔案也不會丟失。而一旦新aof檔案建立完畢,redis就會從舊的aof檔案切換到新的aof檔案,並開始對新的aof檔案進行追加操作。
3、aof檔案有序儲存了對資料庫執行的所有寫入操作,這些寫入操作以redis協議的格式儲存,因此aof檔案內容非常容易被人讀懂,對檔案進行分析也很輕鬆。匯出aof檔案也非常簡單。舉個例子,如果不小心執行了flushall命令,但是只要aof檔案未被重寫,那麼知道停止伺服器,移除aof檔案末尾的flushall命令,並重啟redis,就可以將資料恢復
劣勢1、相對於相同資料集來說,aof檔案體積通常大於rdb檔案
2、根據所用是的fsync策略,aof的速度可能會慢於rdb。在一般情況下,每秒fsync的效能依然非常高,而關閉 fsync 可以讓 aof 的速度和 rdb 一樣快, 即使在高負荷之下也是如此。 不過在處理巨大的寫入載入時,rdb 可以提供更***的最大延遲時間(latency)。
3、aof有發生過bug:因為個別命令的原因,導致aof檔案重新載入時,無法將資料集恢復成儲存時的模樣。(舉個例子,阻塞命令 brpoplpush 就曾經引起過這樣的 bug 。) 測試套件裡為這種情況新增了測試: 它們會自動生成隨機的、複雜的資料集, 並通過重新載入這些資料來確保一切正常。 雖然這種 bug 在 aof 檔案中並不常見, 但是對比來說, rdb 幾乎是不可能出現這種 bug 的。
抉擇一般來說, 如果想達到足以媲美 postgresql 的資料安全性, 你應該同時使用兩種持久化功能。
如果你非常關心你的資料, 但仍然可以承受數分鐘以內的資料丟失, 那麼你可以只使用 rdb 持久化。
其餘情況我個人喜好選擇aof
詳解Redis持久化機制
兩種redis持久化機制之間的區別?兩種redis持久化機制的優缺點?如何選擇合適的持久化機制?一句話 持久化就是把記憶體的資料寫到磁碟中去,防止服務宕機了記憶體資料丟失。redis rdb持久化機制 redis aof持久化機制 rdb持久化是指在指定的時間間隔內將記憶體中的資料集快照寫入磁碟,實...
Redis 持久化機制
持久化資料 就是將記憶體中的資料寫入到硬碟裡面,原因 為了之後重用資料 比如重啟機器 機器故障之後恢復資料 或者是為了防止系統故障而將資料備份到乙個遠端位置 redis通過快照來獲得在某個時間點上記憶體裡面的資料副本。redis建立快照之後,可以對快照進行備份,可以將快照複製到其他伺服器從而建立具有...
Redis的持久化機制
該持久化方式實際是在redis內部乙個定時器事件,每隔固定時間去檢查當前資料發生的改變次數與時間是否滿足配置的持久化觸發的條件,如果滿足則通過作業系統fork呼叫來建立出乙個子程序,這個子程序缺省會與父程序共享相同的位址空間,這時就可以通過子程序來遍歷整個記憶體來進行儲存操作,而主程序則仍然可以提供...