Redis的兩種持久化操作RDB-AOF

相對(duì)來(lái)說(shuō)RDB這種持久化模式更加適合較多的場(chǎng)景

以下轉(zhuǎn)載

Redis支持RDB和AOF兩種持久化機(jī)制,持久化功能有效地避免因進(jìn)程退出造成的數(shù)據(jù)丟失問題矾策,當(dāng)下次重啟時(shí)利用之前持久化文件即可實(shí)現(xiàn)數(shù)據(jù)恢復(fù)宛乃。

1. RDB是什么

RDB持久化是把當(dāng)前進(jìn)程數(shù)據(jù)生成快照保存到硬盤的過(guò)程悠咱,觸發(fā)RDB持久化過(guò)程分為**手動(dòng)觸發(fā)**和**自動(dòng)觸發(fā)**。

1.1.1 觸發(fā)機(jī)制

手動(dòng)觸發(fā)分別對(duì)應(yīng)save和bgsave命令:

save命令:阻塞當(dāng)前Redis服務(wù)器征炼,知道RDB過(guò)程完成為止析既,對(duì)于內(nèi)存比較大的實(shí)例會(huì)造成長(zhǎng)時(shí)間阻塞,先上環(huán)境不建議使用柒室。運(yùn)行save命令對(duì)應(yīng)Redis日志如下:

DB saved on disk

bgsave命令:Redis進(jìn)程執(zhí)行fork操作創(chuàng)建子進(jìn)程渡贾,RDB持久化過(guò)程由子進(jìn)程負(fù)責(zé),完成后自動(dòng)結(jié)束雄右。阻塞只發(fā)生在fork階段空骚,一段時(shí)間很短。運(yùn)行bgsave名字對(duì)應(yīng)的Redis日志如下:

Background saving started by pid 3152
DB saved on disk
RDB: 0MB of memory userd by copy-on-write
Background saving terminated with success

bgsave命令是針對(duì)save阻塞問題做的優(yōu)化擂仍。因此Redis內(nèi)部所有涉及到RDB操作都采用bgsave的方式囤屹,而save命令可以廢棄。

Redis內(nèi)部還存在自動(dòng)觸發(fā)RDB的持久化機(jī)制逢渔,例如一下場(chǎng)景:

1) 使用save相關(guān)配置肋坚,如‘save m n’表示m秒之內(nèi)數(shù)據(jù)集存在n次修改時(shí),自動(dòng)觸發(fā)bgsave。

2)如果從節(jié)點(diǎn)執(zhí)行全量復(fù)制操作智厌,主節(jié)點(diǎn)自動(dòng)執(zhí)行bgsave生成RDB文件并發(fā)送給從節(jié)點(diǎn)诲泌。

3)執(zhí)行debug reload命令重新加載Redis時(shí),也會(huì)自動(dòng)觸發(fā)save操作铣鹏。

4)默認(rèn)情況下執(zhí)行shutdown命令時(shí)敷扫,如果沒有開啟AOF持久化功能則自動(dòng)執(zhí)行bgsave。

1.1.2 bgsave流程說(shuō)明

bgsave是主流的觸發(fā)RDB持久化方式诚卸,下圖是運(yùn)作流程
111.png
  1. 執(zhí)行bgsave命令葵第,Redis父進(jìn)程判斷當(dāng)前是否存在正在執(zhí)行的子進(jìn)程,如只RDB/AOF子進(jìn)程合溺,如果存在bgsave命令直接返回卒密。

  2. 父進(jìn)程執(zhí)行fork操作創(chuàng)建子進(jìn)程,fork操作過(guò)程中父進(jìn)程會(huì)阻塞棠赛,通過(guò)info stats命令查看latest_fork_usec選項(xiàng)哮奇,可以獲取最近一個(gè)fork以操作的耗時(shí),單位為微秒睛约。

  3. 父進(jìn)程仍fork完成后屏镊,bgsave命令返回“Background saving started”信息并不再阻塞父進(jìn)程,可以繼續(xù)響應(yīng)其他命令痰腮。

  4. 子進(jìn)程創(chuàng)建RDB文件,根據(jù)父進(jìn)程內(nèi)存生成臨時(shí)快照文件律罢,完成后對(duì)原有文件進(jìn)行原子替換膀值。執(zhí)行l(wèi)astsave命令可以獲取最后一次生成尺RDB的時(shí)間,對(duì)應(yīng)info統(tǒng)計(jì)的rdb_last_save_time選項(xiàng)误辑。

  5. 進(jìn)程發(fā)送信號(hào)給父進(jìn)程衣示完成沧踏,父進(jìn)程更新統(tǒng)計(jì)信息,具體見info Persistence下的rdb_*相關(guān)選項(xiàng)巾钉。

1.1.3 RDB文件處理

保存:RDB文件保存在dir配置指定的目錄下翘狱,文件名通過(guò)dbfilename配置指定∨椴裕可以通過(guò)執(zhí)行config set dir {newDir} 和 config set dbfilename {newFileName}運(yùn)行期動(dòng)態(tài)執(zhí)行潦匈,當(dāng)下次運(yùn)行時(shí)RDB文件會(huì)保存到新目錄。

壓縮:Redis默認(rèn)采用LZF算法對(duì)生成的RDB文件做壓縮處理赚导,壓縮后的文件遠(yuǎn)遠(yuǎn)小于內(nèi)存大小茬缩,默認(rèn)開啟,可以通過(guò)參數(shù)config set rdbcompression {yes|no}動(dòng)態(tài)修改吼旧。

校驗(yàn):如果Redis加載損壞的RDB文件時(shí)拒絕啟動(dòng)凰锡,并打印如下日志:

Short read or OOM loading DB. Unrecoverable error , aborting now.

這時(shí)可以使用Redis提供的redis-check-dump工具檢測(cè)RDB文件并獲取對(duì)應(yīng)的錯(cuò)誤報(bào)告

1.1.4 RDB的優(yōu)缺點(diǎn)

RDB的優(yōu)點(diǎn):
  • RDB是一個(gè)緊湊壓縮的二進(jìn)制文件,代表Redis在某一個(gè)時(shí)間點(diǎn)上的數(shù)據(jù)快照。非常適合用于備份掂为,全量復(fù)制等場(chǎng)景裕膀。比如每6小時(shí)執(zhí)行bgsave備份,并把RDB文件拷貝到遠(yuǎn)程機(jī)器或者文件系統(tǒng)中(如hdfs)勇哗,用于災(zāi)難恢復(fù)昼扛。

  • Redis加載RDB恢復(fù)數(shù)據(jù)遠(yuǎn)遠(yuǎn)快于AOF方式。

    RDB的缺點(diǎn)

  • RDB方式數(shù)據(jù)沒辦法做到實(shí)時(shí)持久化/秒級(jí)持久化智绸。因?yàn)閎gsave每次運(yùn)行都要執(zhí)行fork操作創(chuàng)建子進(jìn)程野揪,屬于重量級(jí)操作,頻繁執(zhí)行成本過(guò)高瞧栗。

  • RDB文件使用特定二進(jìn)制格式保存斯稳,Redis版本演進(jìn)過(guò)程中有多個(gè)格式的RDB笨笨,存在老版本Redis服務(wù)無(wú)法兼容新版RDB格式的問題迹恐。

    針對(duì)RDB不適合實(shí)時(shí)持久化的問題挣惰,Redis提供了AOF持久化方式來(lái)解決

2. AOF是什么

AOF(append only file)持久化:以獨(dú)立日志的方式記錄每次寫命令,重啟時(shí)再重新執(zhí)行AOF文件中命令達(dá)到恢復(fù)數(shù)據(jù)的目的殴边。AOF的主要作用是解決了數(shù)據(jù)持久化的實(shí)時(shí)性憎茂,目前已經(jīng)是Redis持久化的主流方式。

2.1.1 使用AOF

開啟AOF功能需要設(shè)置配置:appendonly yes,默認(rèn)不開啟锤岸。AOF文件通過(guò)appendfilename 配置設(shè)置竖幔,默認(rèn)文件名是appendonly.aof。保存路徑同RDB持久化方式一致是偷。通過(guò)dir配置指定拳氢。AOF的工作流程操作:命令寫入(append)、文件同步(sync)蛋铆、文件重寫(rewrite)馋评、重啟加載(load),工作流程如下:
112.png

流程如下:

1) 所有的寫入命令會(huì)追加到aof_buf(緩沖區(qū))中。

2) AOF緩沖區(qū)根據(jù)對(duì)應(yīng)的策略向硬盤做同步操作刺啦。

3) 隨著AOF文件越來(lái)越大留特,需要定期對(duì)AOF文件進(jìn)行重寫,達(dá)到壓縮的目的玛瘸。

4) 當(dāng)Redis服務(wù)重啟時(shí)蜕青,可以加載AOF文件進(jìn)行數(shù)據(jù)恢復(fù)。了解AOF工作流程之后糊渊,下面針對(duì)每個(gè)步驟做詳細(xì)介紹市咆。

2.1.2 命令寫入

AOF命令寫入的內(nèi)容直接是文本協(xié)議格式。例如set hello world 這條命令再来,在AOF緩沖區(qū)會(huì)追加如下文本:

\r\n3\r\nset\r\n5\r\nhello\r\n$5\r\nworld\r\n

介紹關(guān)于AOF的連個(gè)疑惑:

1) AOF為什么直接采用文本協(xié)議格式蒙兰?可能的理由如下:
    • 文本協(xié)議具有很好的兼容性磷瘤。

    • 開啟AOF后,所有寫入命令都包含追加操作搜变,直接采用協(xié)議格式采缚,避免二次處理開銷。

    • 文本協(xié)議具有可讀性挠他,方便直接修改和處理扳抽。

    2) AOF為什么把命令追加到aof_buf中?Redis使用單線程響應(yīng)命令殖侵,如果每次寫AOF文件命令都直接追加到硬盤贸呢,那么性能完全取決于當(dāng)前硬盤負(fù)載÷>縣寫入緩沖區(qū)aof_buf中楞陷,還有另一個(gè)好處,Redis可以提供多種緩沖區(qū)同步硬盤的策略茉唉,在性能和安全性方面做出平衡固蛾。

2.1.3 文件同步

Redis提供了多種AOF緩沖區(qū)同步文件策略,由參數(shù)appendfsync控制度陆,不同值的含義如表所示
113.png
系統(tǒng)調(diào)用writ和fsync說(shuō)明:
  • write操作會(huì)處罰延遲寫(delayed write)機(jī)制艾凯,Linux在內(nèi)核提供頁(yè)緩沖區(qū)用來(lái)提高硬盤IO性能。write操作在寫入系統(tǒng)緩沖區(qū)后直接返回懂傀。同步硬盤操作依賴于系統(tǒng)調(diào)度機(jī)制趾诗,列如:緩沖區(qū)頁(yè)空間寫滿或達(dá)到特定時(shí)間周期。同步文件之前蹬蚁,如果此時(shí)系統(tǒng)故障宕機(jī)沧竟,緩沖區(qū)內(nèi)數(shù)據(jù)將丟失。

  • fsync針對(duì)單個(gè)文件操作(比如AOF文件)缚忧,做強(qiáng)制硬盤同步,fsync將阻塞知道寫入硬盤完成后返回杈笔,保證了數(shù)據(jù)持久化闪水。

    除了write、fsync蒙具、Linx還提供了sync球榆、fdatasync操作,具體API說(shuō)明參見:http://linux.die.net/man/2/write

  • 配置為always時(shí)禁筏,每次寫入都要同步AOF文件持钉,在一般的STAT硬盤上,Redis只能支持大約幾百TPS寫入篱昔,顯然跟Redis高性能特性背道而馳每强,不建議配置始腾。

  • 配置為no,由于操作系統(tǒng)每次同步AOF文件的周期不可控,而且會(huì)極大每次同步硬盤的數(shù)據(jù)量空执,雖然提升了性能浪箭,但數(shù)據(jù)安全性無(wú)法保證。

  • 配置為everysec,是建議的同步策略辨绊,也是默認(rèn)配置奶栖,做到兼顧性能和數(shù)據(jù)安全性,理論上只有在系統(tǒng)突然宕機(jī)的情況下丟失1s的數(shù)據(jù)门坷。(嚴(yán)格來(lái)說(shuō)最多丟失1s數(shù)據(jù)是不準(zhǔn)確)

2.1.4 重寫機(jī)制

隨著命令不斷寫入AOF宣鄙,文件會(huì)越來(lái)越大,為了解決這個(gè)問題默蚌,Redis引入了AOF重寫機(jī)制壓縮文件體積冻晤。AOF文件重寫是吧Redis進(jìn)程內(nèi)的數(shù)據(jù)轉(zhuǎn)化為寫命令同步到新AOF文件的過(guò)程。

重寫后的AOF文件為什么可以變下敏簿?有如下原因:

1) 進(jìn)程內(nèi)已經(jīng)超時(shí)的數(shù)據(jù)不再寫文件明也。

2)舊的AOF文件含有無(wú)效命令,如del key1惯裕、 hdel key2温数、srem keys、set a 111蜻势、set a 222等撑刺。重寫使用進(jìn)程內(nèi)數(shù)據(jù)直接生成,這樣新的AOF文件只保留最終數(shù)據(jù)的寫入命令握玛。

3) 多條寫命令可以合并為一個(gè)够傍,如lpush list a、lpush list b挠铲、 lpush list c 可以轉(zhuǎn)化為:lpush list a b c冕屯。為了防止但挑明了過(guò)大造成客戶端緩沖區(qū)溢出,對(duì)于list拂苹、set安聘、hash、zset等類型曹組瓢棒,以64個(gè)元素為界拆分為多條浴韭。 

AOF重寫降低了文件占用空間,除此之外脯宿,另一個(gè)目的是:更小的AOF文件可以更快地被Redis加載念颈。

AOF重寫過(guò)程可以手動(dòng)觸發(fā)和自動(dòng)觸發(fā):
  • 手動(dòng)觸發(fā):直接調(diào)用bgrewriteaof命令

  • 自動(dòng)觸發(fā):更具auto-aof-rewrite-min-size和auto-aof-rewrite-percentage參數(shù)確定自動(dòng)觸發(fā)時(shí)機(jī)

    • auto-aof-rewrite-min-size:表示運(yùn)行AOF重寫時(shí)文件最小體積,默認(rèn)為64MB

    • auto-aof-rewrite-percentage:代表當(dāng)前AOF文件空間(aof_current_size)和上一次重寫后AOF文件空間(aof_base_size)的值

    自動(dòng)觸發(fā)時(shí)機(jī)=aof_current_size>auto-aof-rewrite-min-size && (aof_current_size-aof_base_size) / aof_base_size >= auto-aof-rewrite-percentage

    其中aof_current_size和aof_base_size可以再info Persistence統(tǒng)計(jì)信息中查看连霉。

    當(dāng)觸發(fā)AOF重寫時(shí)榴芳,內(nèi)部做了那些事嗡靡?下面結(jié)合圖介紹它的運(yùn)行流程:

114.png
流程說(shuō)明:

1)執(zhí)行AOF重寫請(qǐng)求。

如果當(dāng)前進(jìn)程正在執(zhí)行AOF重寫翠语,請(qǐng)求不執(zhí)行并返回如下響應(yīng):

ERR Background append only file rewriting already in progress

 如果當(dāng)前進(jìn)程正在執(zhí)行bgsave操作叽躯,重寫命令延遲到bgsave完成后再執(zhí)行,返回如下響應(yīng):

Background append only file rewriting scheduled

2) 父進(jìn)程執(zhí)行fork創(chuàng)建子進(jìn)程肌括,開銷等同于bgsave過(guò)程点骑。

3.1) 主進(jìn)程fork操作完成后,繼續(xù)響應(yīng)其他命令谍夭。所有修改命令依然寫入AOF緩沖區(qū)并更具appendfsync策略同步到硬盤黑滴,保證原有AOF機(jī)制正確性。

3.2) 由于fork操作運(yùn)用寫時(shí)復(fù)制技術(shù)紧索,子進(jìn)程只能共享fork操作時(shí)的內(nèi)存數(shù)據(jù)袁辈。由于父進(jìn)程依然響應(yīng)命令,Redis使用"AOF重寫緩沖區(qū)"保存這部分新數(shù)據(jù)珠漂,防止新AOF文件生成期間丟失這部分?jǐn)?shù)據(jù)晚缩。

4)子進(jìn)程根據(jù)內(nèi)存快照,按照命令合并規(guī)則寫入到新的AOF文件媳危。每次批量寫入硬盤數(shù)據(jù)量由配置aof-rewrite-incremental-fsync控制荞彼,默認(rèn)為32MB,防止單次刷盤數(shù)據(jù)過(guò)多造成硬盤阻塞待笑。

5.1)新AOF文件寫入完成后鸣皂,子進(jìn)程發(fā)送信號(hào)給父進(jìn)程,父進(jìn)程更新統(tǒng)計(jì)信息暮蹂,具體見info persistence下的aof_*相關(guān)統(tǒng)計(jì)寞缝。

5.2)父進(jìn)程把AOF重寫緩沖區(qū)的數(shù)據(jù)寫入到新的AOF文件。

5.3)使用新AOF文件替換老文件仰泻,完成AOF重寫荆陆。

2.1.5 重啟加載

AOF和RDB文件都可以用于服務(wù)器重啟時(shí)的數(shù)據(jù)恢復(fù)。如圖所示集侯,表示Redis持久化文件加載流程:
115.png
流程說(shuō)明:

1) AOF持久化開啟且存在AOF文件時(shí)被啼,優(yōu)先加載AOF文件,打印如下日志:

DB loaded from append only file: 5.841 seconds

2) AOF關(guān)閉或者AOF文件不存在時(shí)浅悉,加載RDB文件,打印如下日志:

DB loaded from disk:5.586 seconds

3) 加載AOF/RDB文件城后券犁,Redis啟動(dòng)成功术健。

4) AOF/RDB文件存在錯(cuò)誤時(shí),Redis啟動(dòng)失敗并打印錯(cuò)誤信息

個(gè)人博客

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末粘衬,一起剝皮案震驚了整個(gè)濱河市荞估,隨后出現(xiàn)的幾起案子咳促,更是在濱河造成了極大的恐慌,老刑警劉巖勘伺,帶你破解...
    沈念sama閱讀 222,865評(píng)論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件跪腹,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡飞醉,警方通過(guò)查閱死者的電腦和手機(jī)冲茸,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)缅帘,“玉大人轴术,你說(shuō)我怎么就攤上這事∏瘴蓿” “怎么了逗栽?”我有些...
    開封第一講書人閱讀 169,631評(píng)論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)失暂。 經(jīng)常有香客問我彼宠,道長(zhǎng),這世上最難降的妖魔是什么弟塞? 我笑而不...
    開封第一講書人閱讀 60,199評(píng)論 1 300
  • 正文 為了忘掉前任凭峡,我火速辦了婚禮,結(jié)果婚禮上宣肚,老公的妹妹穿的比我還像新娘想罕。我一直安慰自己,他們只是感情好霉涨,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,196評(píng)論 6 398
  • 文/花漫 我一把揭開白布按价。 她就那樣靜靜地躺著,像睡著了一般笙瑟。 火紅的嫁衣襯著肌膚如雪楼镐。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,793評(píng)論 1 314
  • 那天往枷,我揣著相機(jī)與錄音框产,去河邊找鬼。 笑死错洁,一個(gè)胖子當(dāng)著我的面吹牛秉宿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播屯碴,決...
    沈念sama閱讀 41,221評(píng)論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼描睦,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了导而?” 一聲冷哼從身側(cè)響起忱叭,我...
    開封第一講書人閱讀 40,174評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤隔崎,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后韵丑,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體爵卒,經(jīng)...
    沈念sama閱讀 46,699評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,770評(píng)論 3 343
  • 正文 我和宋清朗相戀三年撵彻,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钓株。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,918評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡千康,死狀恐怖享幽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拾弃,我是刑警寧澤值桩,帶...
    沈念sama閱讀 36,573評(píng)論 5 351
  • 正文 年R本政府宣布,位于F島的核電站豪椿,受9級(jí)特大地震影響奔坟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜搭盾,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,255評(píng)論 3 336
  • 文/蒙蒙 一咳秉、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧鸯隅,春花似錦澜建、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至跟畅,卻和暖如春咽筋,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背徊件。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工奸攻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人虱痕。 一個(gè)月前我還...
    沈念sama閱讀 49,364評(píng)論 3 379
  • 正文 我出身青樓睹耐,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親部翘。 傳聞我的和親對(duì)象是個(gè)殘疾皇子硝训,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,926評(píng)論 2 361