redis 持久化方式

來源:互聯網
上載者:User

標籤:方法   形式   完整   only   hal   字元   jpg   安裝   有一個   

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

 

  • Redis DataBase(簡稱RDB)
    • 執行機制:快照,直接將databases中的key-value的二進位形式儲存在了rdb檔案中
    • 優點:效能較高(因為是快照,且執行頻率比aof低,而且rdb檔案中直接儲存的是key-values的二進位形式,對於恢複資料也快)
    • 使用單獨子進程來進行持久化,主進程不會進行任何IO操作,保證了redis的高效能
    • 缺點:在save配置條件之間若發生宕機,此間的資料會丟失
    • RDB是間隔一段時間進行持久化,如果持久化之間redis發生故障,會發生資料丟失。所以這種方式更適合資料要求不嚴謹的時候
  • Append-only file (簡稱AOF)
    • 執行機制:將對資料的每一條修改命令追加到aof檔案
    • 優點:資料不容易丟失
    • 可以保持更高的資料完整性,如果設定追加file的時間是1s,如果redis發生故障,最多會丟失1s的資料;且如果日誌寫入不完整支援redis-check-aof來進行日誌修複;AOF檔案沒被rewrite之前(檔案過大時會對命令進行合并重寫),可以刪除其中的某些命令(比如誤操作的flushall)
    • 缺點:效能較低(每一條修改操作都要追加到aof檔案,執行頻率較RDB要高,而且aof檔案中儲存的是命令,對於恢複資料來講需要逐行執行命令,所以恢複慢)
    • AOF檔案比RDB檔案大,且恢複速度慢。

 

除了這兩種方法,Redis在早起的版本還存在虛擬記憶體的方法,現在已經被廢棄。

一、RDB概述

RDB是在某個時間點將資料寫入一個臨時檔案,持久化結束後,用這個臨時檔案替換上次持久化的檔案,達到資料恢複。

這裡說的這個執行資料寫入到臨時檔案的時間點是可以通過配置來自己確定的,通過配置redis在n秒內如果超過m個key被修改這執行一次RDB操作。這個操作就類似於在這個時間點來儲存一次Redis的所有資料,一次快照資料。所有這個持久化方法也通常叫做snapshots。

RDB預設開啟,redis.conf中的具體配置參數如下;

  1.  #dbfilename:持久化資料存放區在本地的檔案
  2.  dbfilename dump.rdb
  3.  #dir:持久化資料存放區在本地的路徑,如果是在/redis/redis-3.0.6/src下啟動的redis-cli,則資料會儲存在當前src目錄下
  4.  dir ./
  5.  ##snapshot觸發的時機,save <seconds> <changes>
  6.  ##如下為900秒後,至少有一個變更操作,才會snapshot
  7.  ##對於此值的設定,需要謹慎,評估系統的變更操作密集程度
  8.  ##可以通過“save “””來關閉snapshot功能 (即禁止使用rdb)
#save時間,以下分別表示更改了1個key時間隔900s進行持久化儲存;更改了10個key300s進行儲存;更改10000個key60s進行儲存。save 900 1save 300 10save 60 10000
  1.  ##當snapshot時出現錯誤無法繼續時,是否阻塞用戶端“變更操作”,“錯誤”可能因為磁碟已滿/磁碟故障/OS層級異常等
  2.  #當後台RDB進程匯出快照(一部分的key-value)到rdb檔案這個過程出錯時(即最後一次的後台儲存失敗時),
  3.  #redis主進程是否還接受向資料庫寫資料
  4.  #該種方式會讓使用者知道在資料持久化到硬碟時出錯了(相當於一種監控);
  5.  #如果安裝了很好的redis持久化監控,可設定為"no" 
stop-writes-on-bgsave-error yes  ##是否啟用rdb檔案壓縮,預設為“yes”,壓縮往往意味著“額外的cpu消耗”,同時也意味這較小的檔案尺寸以及較短的網路傳輸時間 (如果希望RDB進程節省一點CPU時間,設定為no,但是可能最後的rdb檔案會很大)
  1.  rdbcompression yes 
  2.  #在redis重啟後,從rdb檔案向記憶體寫資料之前,是否先檢測該rdb檔案是否損壞(根據rdb檔案中的校正和check_sum)
  3.  rdbchecksum yes

snapshot觸發的時機,是有“間隔時間”和“變更次數”共同決定,同時符合2個條件才會觸發snapshot,否則“變更次數”會被繼續累加到下一個“間隔時間”上。snapshot過程中並不阻塞用戶端請求。snapshot首先將資料寫入臨時檔案,當成功結束後,將臨時檔案重名為dump.rdb。

 

  • 以上三條save命令只要發生任一條,bgsave命令都會發生,這就有兩個問題,假設60s內有10000個key發生了改變(寫入、刪除、更新),那麼是否會立即進行持久化呢?在這次持久化之後,假設又過了240s,而在此期間沒有任何的key的改變操作,此時是否要發生一次持久化(因為滿足300s發生了10個key的改變,這裡是改變了10000個key)?
    • 不會立即進行持久化:redis預設每隔100ms使用serverCron函數檢查一次save配置的條件是否滿足,滿足則進行bgsave,這樣的話,如果在100ms內,我已經滿足了bgsave的條件,那麼我真正執行bgsave的時候也要等到serverCron執行過來的時候
    • 不會再發生持久化:redis有兩個參數dirty(記錄上一次bgsave之後的key的修改數,上邊的在240s內例子就是0)和lastsave(上一次成功執行bgsave命令的時間),配置中的每一個save配置的修改數指的就是dirty,而每一個時間段就是以lastsave為起點計算的。
  • 注釋掉所有的save命令,RDB將不起作用
  • rdbcompression yes:配置成這樣是不是每一個字串在儲存到rdb檔案中時,都要進行一次壓縮操作?
    • 不是:設定為yes之後,只有當字串的長度大於等於21個位元組時,才會進行壓縮
  • rdbchecksum yes:這個校正和儲存在哪裡?為什麼通過比對校正和可以判斷檔案是否損壞?
    • 校正和(check_sum)儲存在RDB檔案的最後八個位元組中(詳細的RDB檔案結構,查看《Redis這基於實現》"第10章 RDB持久化"),簡單的RDB檔案結構如下:
      • RDB檔案開頭的前五個位元組"REDIS"是判斷一個檔案是不是RDB檔案的標準(類似於class檔案中的"魔數")
      • 接下來的4個位元組:RDB檔案版本號碼(db_version)
      • databases(注意是複數):這裡存放各個庫redisDb中儲存的key-value資訊(是整個資料持久化和恢複的核心)
      • EOF(1個位元組):RDB檔案本文的結束
      • check_sum(8個位元組):檢驗和,該值是根據前邊四部分值算出來的,在持久化的時候將該值算出來並寫入rdb檔案的末尾;在根據rdb檔案恢複資料的時候,再根據rdb檔案中的前邊四部分值計算出一個校正和,然後與當前rdb檔案中的check_sum(即後八個位元組)的內容進行比對,如果一樣,說明沒損壞,如果不一樣,說明前四部分有資料損毀(即該檔案損壞)
  • 在Redis伺服器啟動時,redis會自動檢測是否有rdb檔案(前提是沒有aof的時候),如果有,則根據rdb檔案恢複資料,此時在恢複資料完成之前,會阻塞用戶端對redis的讀寫操作

 

 

使用RDB恢複資料:
自動的持久化資料存放區到dump.rdb後。實際只要重啟redis服務即可完成(啟動redis的server時會從dump.rdb中先同步資料)

用戶端使用命令進行持久化save儲存:

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

一個是在前台進行儲存,一個是在後台進行儲存。我的client就在server這台伺服器上,所以不需要連其他機器,直接./redis-cli bgsave。由於redis是用一個主線程來處理所有 client的請求,這種方式會阻塞所有client請求。所以不推薦使用。另一點需要注意的是,每次快照持久化都是將記憶體資料完整寫入到磁碟一次,並不是增量的只同步髒資料。如果資料量大的話,而且寫操作比較多,必然會引起大量的磁碟io操作,可能會嚴重影響效能。

二、AOF概述

Append-only file,將“操作 + 資料”以格式化指令的方式追加到動作記錄檔案的尾部,在append操作返回後(已經寫入到檔案或者即將寫入),才進行實際的資料變更,“記錄檔”儲存了曆史所有的操作過程;當server需要資料恢複時,可以直接replay此記錄檔,即可還原所有的操作過程。AOF相對可靠,它和mysql中bin.log、apache.log、zookeeper中txn-log簡直異曲同工。AOF檔案內容是字串,非常容易閱讀和解析。

我們可以簡單的認為AOF就是記錄檔,此檔案只會記錄“變更操作”(例如:set/del等),如果server中持續的大量變更操作,將會導致AOF檔案非常的龐大,意味著server失效後,資料恢複的過程將會很長;事實上,一條資料經過多次變更,將會產生多條AOF記錄,其實只要儲存當前的狀態,曆史的操作記錄是可以拋棄的;因為AOF持久化模式還伴生了“AOF rewrite”。
AOF的特性決定了它相對比較安全,如果你期望資料更少的丟失,那麼可以採用AOF模式。如果AOF檔案正在被寫入時突然server失效,有可能導致檔案的最後一次記錄是不完整,你可以通過手工或者程式的方式去檢測並修正不完整的記錄,以便通過aof檔案恢複能夠正常;同時需要提醒,如果你的redis持久化手段中有aof,那麼在server故障失效後再次啟動前,需要檢測aof檔案的完整性。

AOF預設關閉,開啟方法,修改設定檔reds.conf:appendonly yes

  1.  ##此選項為aof功能的開關,預設為“no”,可以通過“yes”來開啟aof功能
  2.  ##只有在“yes”下,aof重寫/檔案同步等特性才會生效
  3.  appendonly yes
  4.   
  5.  ##aof檔案的存放路徑與檔案名稱
  6.  appendfilename appendonly.aof
  7.   
  8.  ##指定aof操作中檔案同步策略,有三個合法值:always everysec no,預設為everysec
  9.  ##always 每一個命令,都立即同步到aof檔案中去(很安全,但是速度慢,因為每一個命令都會進行一次磁碟操作)IO開支較大。
  10.  ##everysec每秒將資料寫一次到aof檔案,redis推薦的方式。如果遇到物理伺服器故障,有可能導致最近一秒內aof記錄丟失(可能為部分丟失)。
  11.  ##no 將寫入工作交給作業系統,由作業系統來判斷緩衝區大小,統一寫到aof檔案(速度快,但是同步頻率低,容易丟資料)
  12.   appendfsync everysec
  13.  ##在aof-rewrite期間,appendfsync是否暫緩檔案同步,"no"表示“不暫緩”,“yes”表示“暫緩”,預設為“no”
  14.  # 在RDB持久化資料的時候,此時的aof操作是否停止,若為yes則停止
  15.  # 在停止的這段時間內,執行的命令會寫入記憶體隊列,等RDB持久化完成後,統一將這些命令寫入aof檔案
  16.  # 該參數的配置是考慮到RDB持久化執行的頻率低,但是執行的時間長,而AOF執行的頻率高,執行的時間短,
  17.  # 若同時執行兩個子進程(RDB子進程、AOF子進程)效率會低(兩個子進程都是磁碟讀寫)
  18.  # 但是若改為yes可能造成的後果是,由於RDB持久化執行時間長,在這段時間內有很多命令寫入了記憶體隊列,
  19.  # 最後導致隊列放不下,這樣AOF寫入到AOF檔案中的命令可能就少了很多
  20.  # 在恢複資料的時候,根據aof檔案恢複就會丟很多資料
  21.  # 所以,選擇no就好
  22.  no-appendfsync-on-rewrite no
  23.   
  24.  ##aof檔案rewrite觸發的最小檔案尺寸(mb,gb),只有大於此aof檔案大於此尺寸是才會觸發rewrite,預設“64mb”,建議“512mb”
  25.  ## AOF重寫:把記憶體中的資料逆化成命令,然後將這些命令重新寫入aof檔案
  26.  # 重寫的目的:假設在我們在記憶體中對同一個key進行了100次操作,最後該key的value是100,
  27.  # 那麼在aof中就會存在100條命令日誌,這樣的話,有兩個缺點:
  28.  # 1)AOF檔案過大,佔據硬碟空間 2)根據AOF檔案恢複資料極慢(需要執行100條命令)
  29.  # 如果我們將記憶體中的該key逆化成"set key 100",然後寫入aof檔案,
  30.  # 那麼aof檔案的大小會大幅度減少,而且根據aof檔案恢複資料很快(只需要執行1條命令)
  31.  # 注意:下邊兩個約束都要滿足的條件下,才會發生aof重寫;
  32.  # 假設沒有第二個,那麼在aof的前期,只要稍微添加一些資料,就發生aof重寫
  33.  # 當aof的增長的百分比是原來的100%(即是原來大小的2倍,例如原來是100m,下一次重寫是當aof檔案是200m的時候),AOF重寫
  34.  auto-aof-rewrite-min-size 64mb
  35.   
  36.  ##相對於“上一次”rewrite,本次rewrite觸發時aof檔案應該增長的百分比。
  37.  ##每一次rewrite之後,redis都會記錄下此時“新aof”檔案的大小(例如A),那麼當aof檔案增長到A*(1 + p)之後
  38.  ##觸發下一次rewrite,每一次aof記錄的添加,都會檢測當前aof檔案的尺寸。
  39.  auto-aof-rewrite-percentage 100

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

因為rewrite操作/aof記錄同步/snapshot都消耗磁碟IO,redis採取了“schedule”策略:無論是“人工幹預”還是系統觸發,snapshot和rewrite需要逐個被執行。

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

三.總結:

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

1) AOF更加安全,可以將資料更加及時的同步到檔案中,但是AOF需要較多的磁碟IO開支,AOF檔案尺寸較大,檔案內容恢複數度相對較慢。

*2) snapshot,安全性較差,它是“正常時期”資料備份以及master-slave資料同步的最佳手段,檔案尺寸較小,恢複數度較快

 

  • 如果既配置了RDB,又配置了AOF,則在進行資料持久化的時候,都會進行,但是在根據檔案恢複資料的時候,以AOF檔案為準,RDB檔案作廢
    • 需要注意:資料的恢複是阻塞操作(此間所到來的任何用戶端讀寫請求都失效)
  • bgsave和bgrewriteaof(後台aof重寫)這兩個命令不可以同時發生
    • 如果bgsave在執行,此間到來的bgrewriteaof在bgsave執行之後,再執行
    • 如果bgrewriteaof在執行,此間到來的bgsave丟棄
  • RDB和AOF可以同時配置,但是最後還原資料庫的時候是以aof檔案來還原的

--------------------- 本文來自 xiaozhu0301 的CSDN 部落格 ,全文地址請點擊:79021436?utm_source=copy 

redis 持久化方式

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.