redis-rdb&aof

RDB

RDB是在某個時間點將數據寫入一個臨時文件,持久化結束後,用這個臨時文件替換上次持久化的文件,達到數據恢復。

優勢:使用單獨子進程來進行持久化,主進程不會進行任何IO操做,保證了redis的高性能

缺點:RDB是間隔一段時間進行持久化,若是持久化之間redis發生故障,會發生數據丟失。因此這種方式更適合數據要求不嚴謹的時候
複製代碼

配置信息

save 900 1
save 300 10
save 60 10000
snapshot觸發的時機,是有「間隔時間」和「變動次數」共同決定,同時符合2個條件纔會觸發snapshot,不然「變動次數」會被繼續累加到下一個「間隔時間」上。snapshot過程當中並不阻塞客戶端請求。snapshot首先將數據寫入臨時文件,當成功結束後,將臨時文件重名爲dump.rdb。
複製代碼

RDB觸發機制

1.save命令:阻塞當前redis服務器,直到RDB過程完成爲止,若是redis數據較多,可能形成redis進程的長時間阻塞。

2.bgsave: redis執行fork建立子進程,RDB持久化過程由這個子進程負責,完成以後結束。
複製代碼

流程圖

RDB恢復數據

RDB文件的載入工做是在服務器啓動時自動執行的,並無專門的命令。可是因爲AOF的優先級更高,所以當AOF開啓時,Redis會優先載入AOF文件來恢復數據;只有當AOF關閉時,纔會在Redis服務器啓動時檢測RDB文件,並自動載入。服務器載入RDB文件期間處於阻塞狀態,直到載入完成爲止。

Redis載入RDB文件時,會對RDB文件進行校驗,若是文件損壞,則日誌中會打印錯誤,Redis啓動失敗。
複製代碼

AOF

  • Append-only file,將「操做 + 數據」以格式化指令的方式追加到操做日誌文件的尾部,在append操做返回後(已經寫入到文件或者即將寫入),才進行實際的數據變動,「日誌文件」保存了歷史全部的操做過程;當server須要數據恢復時,能夠直接replay此日誌文件,便可還原全部的操做過程。AOF相對可靠,它和mysql中bin.log、apache.log、zookeeper中txn-log簡直殊途同歸。AOF文件內容是字符串,很是容易閱讀和解析。mysql

  • 優勢:能夠保持更高的數據完整性,若是設置追加file的時間是1s,若是redis發生故障,最多會丟失1s的數據;且若是日誌寫入不完整支持redis-check-aof來進行日誌修復;AOF文件沒被rewrite以前(文件過大時會對命令進行合併重寫),能夠刪除其中的某些命令(好比誤操做的flushall)。linux

  • 咱們能夠簡單的認爲AOF就是日誌文件,此文件只會記錄「變動操做」(例如:set/del等),若是server中持續的大量變動操做,將會致使AOF文件很是的龐大,意味着server失效後,數據恢復的過程將會很長;事實上,一條數據通過屢次變動,將會產生多條AOF記錄,其實只要保存當前的狀態,歷史的操做記錄是能夠拋棄的;由於AOF持久化模式還伴生了「AOF rewrite」。redis

  • AOF的特性決定了它相對比較安全,若是你指望數據更少的丟失,那麼能夠採用AOF模式。若是AOF文件正在被寫入時忽然server失效,有可能致使文件的最後一次記錄是不完整,你能夠經過手工或者程序的方式去檢測並修正不完整的記錄,以便經過aof文件恢復可以正常;同時須要提醒,若是你的redis持久化手段中有aof,那麼在server故障失效後再次啓動前,須要檢測aof文件的完整性。sql

  • AOF是文件操做,對於變動操做比較密集的server,那麼必將形成磁盤IO的負荷加劇;此外linux對文件操做採起了「延遲寫入」手段,即並不是每次write操做都會觸發實際磁盤操做,而是進入了buffer中,當buffer數據達到閥值時觸發實際寫入(也有其餘時機),這是linux對文件系統的優化,可是這卻有可能帶來隱患,若是buffer沒有刷新到磁盤,此時物理機器失效(好比斷電),那麼有可能致使最後一條或者多條aof記錄的丟失。經過上述配置文件,能夠得知redis提供了3中aof記錄同步選項:數據庫

  • 其實,咱們能夠選擇的太少,everysec是最佳的選擇。若是你很是在乎每一個數據都極其可靠,建議你選擇一款「關係性數據庫」吧。AOF文件會不斷增大,它的大小直接影響「故障恢復」的時間,並且AOF文件中歷史操做是能夠丟棄的。**AOF rewrite操做就是「壓縮」AOF文件的過程,固然redis並無採用「基於原aof文件」來重寫的方式,而是採起了相似snapshot的方式:基於copy-on-write,全量遍歷內存中數據,而後逐個序列到aof文件中。所以AOF rewrite可以正確反應當前內存數據的狀態,這正是咱們所須要的;**rewrite過程當中,對於新的變動操做將仍然被寫入到原AOF文件中,同時這些新的變動操做也會被redis收集起來(buffer,copy-on-write方式下,最極端的多是全部的key都在此期間被修改,將會耗費2倍內存),當內存數據被所有寫入到新的aof文件以後,收集的新的變動操做也將會一併追加到新的aof文件中,此後將會重命名新的aof文件爲appendonly.aof,此後全部的操做都將被寫入新的aof文件。若是在rewrite過程當中,出現故障,將不會影響原AOF文件的正常工做,只有當rewrite完成以後纔會切換文件,由於rewrite過程是比較可靠的。apache

  • 能夠經過配置文件來指定它們中的一種,或者同時使用它們(不建議同時使用),或者所有禁用,在架構良好的環境中,master一般使用AOF,slave使用snapshot,主要緣由是master須要首先確保數據完整性,它做爲數據備份的第一選擇;slave提供只讀服務(目前slave只能提供讀取服務),它的主要目的就是快速響應客戶端read請求;可是若是你的redis運行在網絡穩定性差/物理環境糟糕狀況下,建議你master和slave均採起AOF,這個在master和slave角色切換時,能夠減小「人工數據備份」/「人工引導數據恢復」的時間成本;若是你的環境一切很是良好,且服務須要接收密集性的write操做,那麼建議master採起snapshot,而slave採用AOF。安全

aof流程圖

1.全部的寫入命令都會追加到aof_buf(緩衝區)中。
2.AOF緩衝區根據對應的策略向硬盤中作同步操做。
3.隨着AOF文件的增大,須要按期對AOF文件進行重寫,達到壓縮的目的。
4.當Redis服務器重啓的時候,能夠加載AOF文件進行數據恢復。
複製代碼
  • AOF命令的寫入是使用文本協議格式。爲何要首先寫入到緩衝區,是由於Redis是單線程的,若是每次都追加到硬盤中,那麼性能就取決於當前硬盤的負載。
由appendfsync進行控制。

always:每一條aof記錄都當即同步到文件,這是最安全的方式,也覺得更多的磁盤操做和阻塞延遲,
是IO開支較大。

everysec:每秒同步一次,性能和安全都比較中庸的方式,也是redis推薦的方式。若是遇到物理服務器故障,
有可能致使最近一秒內aof記錄丟失(可能爲部分丟失)。

no:redis並不直接調用文件同步,而是交給操做系統來處理,操做系統能夠根據buffer填充狀況/通道空閒時
間等擇機觸發同步;這是一種普通的文件操做方式。性能較好,在物理服務器故障時,數據丟失量會因OS配置有關
複製代碼

重寫機制

1.手動觸發:直接調用bgrewriteaof命令
2.自動觸發:根據auto-aof-rewrite-min-size和auto-aof-rewrite-percentage參數來決定自動觸發。

auto-aof-rewrite-min-size表示運行AOF重寫文件的最小體積
auto-aof-rewrite-percentage表明當前AOF文件空間和上次從寫後AOF文件空間的比值。
複製代碼

1. 執行AOF重寫請求。 若是當前進程正在執行AOF重寫,請求執行。
2. 父進程執行fork建立子進程,開銷等同於bgsave過程。
3. 主進程fork操做完成後,繼續相應其餘命令。全部修改命令依然寫入AOF緩衝區並根絕appendfsync策略同步到硬盤,保證原有AOF機制正確性。fork操做運用寫時複製技術,子進程只能共享fork操做時候的內存數據。因爲父進程依然響應命令,redis使用「AOF
重寫緩衝區」保存這部分西數據,防止新AOF文件生成期間丟失這部分數據。
4. 子進程依據內存快照,按照命令合併規則寫入新的AOF文件。
5.新AOF文件寫入完成以後,子進程發送信號給父進程,父進程統計信息。父進程把AOF重寫緩衝區的數據寫入到新的AOF文件。使用新AOF文件替換老文件,完成AOF重寫。
複製代碼

重啓加載

相關文章
相關標籤/搜索
本站公眾號
   歡迎關注本站公眾號,獲取更多信息