Redis持久化存儲(AOF與RDB兩種模式)

Redis中數據存儲模式有2種:cache-only,persistence;mysql

  • cache-only即只作爲「緩存」服務,不持久數據,數據在服務終止後將消失,此模式下也將不存在「數據恢復」的手段,是一種安全性低/效率高/容易擴展的方式;
  • persistence即爲內存中的數據持久備份到磁盤文件,在服務重啓後能夠恢復,此模式下數據相對安全。

對於persistence持久化存儲,Redis提供了兩種持久化方法:linux

  • Redis DataBase(簡稱RDB)
  • Append-only file (簡稱AOF)

除了這兩種方法,Redis在早起的版本還存在虛擬內存的方法,如今已經被廢棄。redis

1、RDB概述

RDB是在某個時間點將數據寫入一個臨時文件,持久化結束後,用這個臨時文件替換上次持久化的文件,達到數據恢復。 
優勢:使用單獨子進程來進行持久化,主進程不會進行任何IO操做,保證了redis的高性能 
缺點:RDB是間隔一段時間進行持久化,若是持久化之間redis發生故障,會發生數據丟失。因此這種方式更適合數據要求不嚴謹的時候sql

這裏說的這個執行數據寫入到臨時文件的時間點是能夠經過配置來本身肯定的,經過配置redis在n秒內若是超過m個key被修改這執行一次RDB操做。這個操做就相似於在這個時間點來保存一次Redis的全部數據,一次快照數據。全部這個持久化方法也一般叫作snapshots。數據庫

RDB默認開啓,redis.conf中的具體配置參數以下;apache

#dbfilename:持久化數據存儲在本地的文件 dbfilename dump.rdb #dir:持久化數據存儲在本地的路徑,若是是在/redis/redis-3.0.6/src下啓動的redis-cli,則數據會存儲在當前src目錄下 dir ./ ##snapshot觸發的時機,save <seconds> <changes> ##以下爲900秒後,至少有一個變動操做,纔會snapshot ##對於此值的設置,須要謹慎,評估系統的變動操做密集程度 ##能夠經過「save 「」」來關閉snapshot功能 #save時間,如下分別表示更改了1個key時間隔900s進行持久化存儲;更改了10個key300s進行存儲;更改10000個key60s進行存儲。 save 900 1 save 300 10 save 60 10000 ##當snapshot時出現錯誤沒法繼續時,是否阻塞客戶端「變動操做」,「錯誤」可能由於磁盤已滿/磁盤故障/OS級別異常等 stop-writes-on-bgsave-error yes ##是否啓用rdb文件壓縮,默認爲「yes」,壓縮每每意味着「額外的cpu消耗」,同時也意味這較小的文件尺寸以及較短的網絡傳輸時間 rdbcompression yes 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

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

使用RDB恢復數據: 
自動的持久化數據存儲到dump.rdb後。實際只要重啓redis服務便可完成(啓動redis的server時會從dump.rdb中先同步數據)安全

客戶端使用命令進行持久化save存儲:服務器

./redis-cli -h ip -p port save ./redis-cli -h ip -p port bgsave
  • 1
  • 2

一個是在前臺進行存儲,一個是在後臺進行存儲。個人client就在server這臺服務器上,因此不須要連其餘機器,直接./redis-cli bgsave。因爲redis是用一個主線程來處理全部 client的請求,這種方式會阻塞全部client請求。因此不推薦使用。另外一點須要注意的是,每次快照持久化都是將內存數據完整寫入到磁盤一次,並非增量的只同步髒數據。若是數據量大的話,並且寫操做比較多,必然會引發大量的磁盤io操做,可能會嚴重影響性能。網絡

2、AOF概述

Append-only file,將「操做 + 數據」以格式化指令的方式追加到操做日誌文件的尾部,在append操做返回後(已經寫入到文件或者即將寫入),才進行實際的數據變動,「日誌文件」保存了歷史全部的操做過程;當server須要數據恢復時,能夠直接replay此日誌文件,便可還原全部的操做過程。AOF相對可靠,它和mysql中bin.log、apache.log、zookeeper中txn-log簡直殊途同歸。AOF文件內容是字符串,很是容易閱讀和解析。 
優勢:能夠保持更高的數據完整性,若是設置追加file的時間是1s,若是redis發生故障,最多會丟失1s的數據;且若是日誌寫入不完整支持redis-check-aof來進行日誌修復;AOF文件沒被rewrite以前(文件過大時會對命令進行合併重寫),能夠刪除其中的某些命令(好比誤操做的flushall)。 
缺點:AOF文件比RDB文件大,且恢復速度慢。

咱們能夠簡單的認爲AOF就是日誌文件,此文件只會記錄「變動操做」(例如:set/del等),若是server中持續的大量變動操做,將會致使AOF文件很是的龐大,意味着server失效後,數據恢復的過程將會很長;事實上,一條數據通過屢次變動,將會產生多條AOF記錄,其實只要保存當前的狀態,歷史的操做記錄是能夠拋棄的;由於AOF持久化模式還伴生了「AOF rewrite」。 
AOF的特性決定了它相對比較安全,若是你指望數據更少的丟失,那麼能夠採用AOF模式。若是AOF文件正在被寫入時忽然server失效,有可能致使文件的最後一次記錄是不完整,你能夠經過手工或者程序的方式去檢測並修正不完整的記錄,以便經過aof文件恢復可以正常;同時須要提醒,若是你的redis持久化手段中有aof,那麼在server故障失效後再次啓動前,須要檢測aof文件的完整性。

AOF默認關閉,開啓方法,修改配置文件reds.conf:appendonly yes

##此選項爲aof功能的開關,默認爲「no」,能夠經過「yes」來開啓aof功能 ##只有在「yes」下,aof重寫/文件同步等特性纔會生效 appendonly yes ##指定aof文件名稱 appendfilename appendonly.aof ##指定aof操做中文件同步策略,有三個合法值:always everysec no,默認爲everysec appendfsync everysec ##在aof-rewrite期間,appendfsync是否暫緩文件同步,"no"表示「不暫緩」,「yes」表示「暫緩」,默認爲「no」 no-appendfsync-on-rewrite no ##aof文件rewrite觸發的最小文件尺寸(mb,gb),只有大於此aof文件大於此尺寸是纔會觸發rewrite,默認「64mb」,建議「512mb」 auto-aof-rewrite-min-size 64mb ##相對於「上一次」rewrite,本次rewrite觸發時aof文件應該增加的百分比。 ##每一次rewrite以後,redis都會記錄下此時「新aof」文件的大小(例如A),那麼當aof文件增加到A*(1 + p)以後 ##觸發下一次rewrite,每一次aof記錄的添加,都會檢測當前aof文件的尺寸。 auto-aof-rewrite-percentage 100 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

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

  • always:每一條aof記錄都當即同步到文件,這是最安全的方式,也覺得更多的磁盤操做和阻塞延遲,是IO開支較大。
  • everysec:每秒同步一次,性能和安全都比較中庸的方式,也是redis推薦的方式。若是遇到物理服務器故障,有可能致使最近一秒內aof記錄丟失(可能爲部分丟失)。
  • no:redis並不直接調用文件同步,而是交給操做系統來處理,操做系統能夠根據buffer填充狀況/通道空閒時間等擇機觸發同步;這是一種普通的文件操做方式。性能較好,在物理服務器故障時,數據丟失量會因OS配置有關。

其實,咱們能夠選擇的太少,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過程是比較可靠的。*

觸發rewrite的時機能夠經過配置文件來聲明,同時redis中能夠經過bgrewriteaof指使人工干預。

redis-cli -h ip -p port bgrewriteaof
  • 1

由於rewrite操做/aof記錄同步/snapshot都消耗磁盤IO,redis採起了「schedule」策略:不管是「人工干預」仍是系統觸發,snapshot和rewrite須要逐個被執行。

AOF rewrite過程並不阻塞客戶端請求。系統會開啓一個子進程來完成。

三.總結:

AOF和RDB各有優缺點,這是有它們各自的特色所決定:

  • 1) AOF更加安全,能夠將數據更加及時的同步到文件中,可是AOF須要較多的磁盤IO開支,AOF文件尺寸較大,文件內容恢復數度相對較慢。 
    *2) snapshot,安全性較差,它是「正常時期」數據備份以及master-slave數據同步的最佳手段,文件尺寸較小,恢復數度較快。

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

轉自:http://blog.csdn.net/canot/article/details/52886923

相關文章
相關標籤/搜索