淺談Redis的兩種持久化機制

前言

衆所周知,redis是一個內存數據庫,既然是將數據保存在內存中,上下線以後數據天然就會丟失,在咱們的業務中,這種狀況固然是不容許發生的,因此這時候就須要涉及到redis的持久化機制linux

redis能夠手動開啓持久化,來讓內存中的數據持久化到磁盤上,redis提供瞭如下兩種持久化方案:redis

  • RDB快照
  • AOF日誌

接下來咱們就要針對這兩種方式來作一個講解數據庫

RDB快照

rdb快照的原理是對redis中的數據進行週期性的持久化,也能夠理解爲redis每隔一段時間就把當前內存數據的狀態持久化到磁盤中windows

這個具體的操做並非由工做進程來完成的,redis會調用fork函數來建立一個子進程,父進程會正常執行客戶端發來的請求操做,而子進程會把當前的數據庫快照寫入到臨時文件中,最後替換原有的文件(默認爲dump.rdb)緩存

因爲操做系統的copy-on-write機制,父子進程是共享物理頁面的,當父進程處理寫請求時,操做系統爲父進程要修改的頁面建立一個副本,因此子進程地址空間的數據只是當前時刻整個數據庫的一個快照,也這就是把這種方式叫作rdb快照的緣由bash

這種方式的優勢很明顯:服務器

  • RDB模式下會不斷產生快照文件,均表明某一時刻redis中的數據,能夠用做冷備份
  • 採用子進程來執行磁盤IO,寫入快照的時候對redis的影響很是小,能夠保持redis的高性能
  • 重啓和恢復redis數據的速度很快

可是其也有缺點:app

  • 若是在兩次快照之間發生宕機,則其間寫入的數據會丟失
  • 每次fork的時候,若是數據很大,則會產生必定時間的服務暫停

redis是默認開啓這種持久化方式的,能夠打開redis.conf文件,若是是window系統就打開redis.window.conf(redis.windows-service.conf文件是做爲系統服務啓動時加載的配置文件,若是你設置redis爲系統服務,就打開這一個),會發現下面這些配置:函數

save 900 1
save 300 10
save 60 10000
複製代碼

咱們拿save 900 1這條配置來舉例,其含義就是在900秒內,若是至少有1個key值發生了變化,就進行內存快照,咱們查看默認的這些配置也能夠發現,這些save語句是能夠同時出現的,因此你能夠配置不少這樣的rdb快照設置性能

AOF日誌

看名字應該能猜得出,這種持久化模式是採用日誌來進行的,aof模式經過把每條指令追加到日誌文件中(默認爲appendonly.aof文件),當redis重啓後,經過回放aof日誌文件中的操做來實現數據集的恢復

開啓了aof持久化模式後,redis會將全部收到的修改命令經過write函數追加到日誌文件中,具體的執行能夠設置如下3種:

  • always:每次有修改操做就強制寫入
  • everysec:每秒鐘強制寫入(推薦使用)
  • no:不主動進行持久化,將數據存放在操做系統中,通常linux每30分鐘刷新一次數據

這三種模式分別對應配置文件中的appendfsync alwaysappendfsync everysec,和appendfsync no

接着咱們能夠看一下aof日誌的內容,這裏截取了一小段我測試的aof文件:

set
$3
bbb
$3
aaa
*3
$3
set
$3
aaa
$3
ccc
*2
$3
del
$3
aaa
複製代碼

能夠看出,全部的修改命令都是經過命令符-數據庫名-key值這樣的順序來保存的,可讀性也很高

可是aof日誌依然有一個問題,若是咱們反覆地執行set操做,那麼aof日誌中就會重複地保存這些沒必要要的操做,由於這些命令最終的執行結果和一個set命令的執行結果沒有任何區別,那怎麼解決這種數據冗餘問題呢?

其實這一點redis開發人員也想到了,redis提供了bgrewriteaof命令,收到此命令的redis服務器會自動fork出一個子進程,這個子進程會根據內存中的數據快照,來建立一個用於恢復當期數據的最小日誌文件,當寫入完成後,子進程會向父進程發送信號,而後父進程把緩存中的修改命令也寫入這個臨時文件中,並用這個臨時文件來替換原aof文件

這份生成的aof文件你會發現幾乎都是set操做,並且基本不會出現對一個值重複的set命令,因此恢復起來也至關迅速

aof模式的優勢以下:

  • 可讀性很是高,若是發生了誤操做,能夠在rewrite操做以前拷貝一份aof日誌文件,將其中的誤操做刪去,而後替換原有文件便可,不影響redis的恢復讀取,能夠用來做爲緊急恢復
  • 丟失數據的概率很低,即便丟失也不會有太大影響(若是設置了每秒備份,則最多會丟失1s內寫入的數據)

可是也依然有缺點:

  • aof文件通常大於rbd文件
  • 根據選擇的fsync策略的不一樣,aof的速度可能會慢於rdb
  • 在寫入負載很大的狀況下,aof不能提供最大延遲的保證,而rbd能夠
  • 有概率發生不能徹底恢復redis數據的bug

使用場景

在日常使用時,咱們不能說哪一種就是最好的,而要根據實際狀況來選擇,這裏我提供一些選擇的建議:

  • 若是你能夠容許當發生宕機時有幾分鐘的數據丟失,那麼就使用RDB快照模式,它可讓你更快地重啓redis
  • 其他狀況均推薦採用RDB+AOF的模式

沒錯,在使用時能夠同時配置rdb和aof兩種模式,redis官方也推薦咱們這麼作,aof爲主,rdb爲輔,aof記錄日誌,rdb作數據庫備份,以及aof引擎失效後的替代

總結

持久化的講解到這裏基本就結束了,這裏僅僅是帶你們簡要了解了一下redis持久化的內容,本文一部分是我的的理解、總結與實踐,一部分是參考Redis Persistence – Redis這篇官方文檔,若有什麼錯誤歡迎指正

相關文章
相關標籤/搜索