張文帥
摘要:該文針對(duì)Redis數(shù)據(jù)庫(kù)中兩個(gè)問(wèn)題,RDB(Snapshot)恢復(fù)數(shù)據(jù)不完整和AOF(Append Only File)恢復(fù)速度慢,提出了RDB+AOF的數(shù)據(jù)恢復(fù)方案。該方案借鑒檢查點(diǎn)思想,依賴RDB和AOF兩種方法,不但具有AOF恢復(fù)數(shù)據(jù)全面的特點(diǎn),又兼具RDB恢復(fù)速度快的優(yōu)勢(shì)。按照此方案修改Redis源碼并作對(duì)照實(shí)驗(yàn),結(jié)果證明該方案可行且有效。
關(guān)鍵詞:Redis;數(shù)據(jù)恢復(fù);檢查點(diǎn);RDB+AOF
中圖分類號(hào):TP391 文獻(xiàn)標(biāo)識(shí)碼:A 文章編號(hào):1009-3044(2016)14-0007-04
Research on a Data Recovery Strategy Based on RDB and AOF in Redis
ZHANG Wen-shuai
(School of Mechanical Electronic and Information, China University of Ming and Technology(Beijing), Beijing 100083, China)
Abstract: This paper in order to solve two problems in Redis database,one is that the restored data is not complete through RDB(Snapshot),the orther is the speed is slow through AOF(Append Only File),put forword a data recovery method which combined RDB with AOF.The scheme, which is used checkpoint for reference, depends on the two methods of RDB and AOF, which not only has the characteristics of comprehensive recovery like AOF, but also has the advantage of rapid recovery like RDB.In accordance with this program to modify the Redis' source code and do a control experiment, the results show that the program is feasible and effective.
Key words: Redis; data recovery; checkpoint; RDB+AOF
數(shù)據(jù)庫(kù)技術(shù)的發(fā)展,帶動(dòng)了NoSQL(非關(guān)系數(shù)據(jù)庫(kù))的崛起,其中Redis(REmote DIctionary Server)數(shù)據(jù)庫(kù)因其高效性得到廣泛應(yīng)用。它是一個(gè)用C語(yǔ)言編寫的開源的內(nèi)存數(shù)據(jù)庫(kù),支持?jǐn)?shù)據(jù)持久化。
持久化是內(nèi)存數(shù)據(jù)庫(kù)數(shù)據(jù)恢復(fù)的前提。Redis支持兩種數(shù)據(jù)持久化方法:一種是RDB,能周期性地對(duì)數(shù)據(jù)庫(kù)做快照并寫入磁盤。RDB恢復(fù)速度較快,但兩次快照期間的數(shù)據(jù)都會(huì)丟失;另一種是AOF,將每次寫操作都記錄日志,并定期寫入磁盤。AOF恢復(fù)速度較慢,但能恢復(fù)全部數(shù)據(jù),不會(huì)造成數(shù)據(jù)丟失的現(xiàn)象。
本文通過(guò)分析RDB和AOF的原理和特點(diǎn),結(jié)合多種數(shù)據(jù)庫(kù)在數(shù)據(jù)恢復(fù)技術(shù)方面的方法和經(jīng)驗(yàn),提出了一種RDB+AOF相結(jié)合的方案,該方案將解決RDB恢復(fù)數(shù)據(jù)不完整和AOF恢復(fù)速度慢的缺點(diǎn),對(duì)于Redis能夠完整快速恢復(fù)數(shù)據(jù)具有很重要的實(shí)用意義。
1 數(shù)據(jù)庫(kù)恢復(fù)技術(shù)概述
1.1 關(guān)系數(shù)據(jù)庫(kù)恢復(fù)技術(shù)
關(guān)系數(shù)據(jù)庫(kù)恢復(fù)技術(shù)主要有數(shù)據(jù)轉(zhuǎn)儲(chǔ)和登錄日志文件兩種,為了維護(hù)事務(wù)的特性,必須使用日志方式,以便數(shù)據(jù)恢復(fù)時(shí)可以進(jìn)行相應(yīng)的redo(重做)和undo(撤銷)操作,維持事務(wù)一致性。為了解決日志恢復(fù)速度慢的缺陷,關(guān)系數(shù)據(jù)庫(kù)在日志基礎(chǔ)上發(fā)展了檢查點(diǎn)技術(shù)。
傳統(tǒng)日志恢復(fù)方法需要遍歷整個(gè)日志文件,且要重新執(zhí)行所有操作,這將造成很多時(shí)間浪費(fèi),為此發(fā)展了檢查點(diǎn)技術(shù)。該技術(shù)在日志文件中增加檢查點(diǎn),檢查點(diǎn)是這個(gè)時(shí)刻數(shù)據(jù)庫(kù)的一致性備份,再增加一個(gè)重新開始文件,用于記錄檢查點(diǎn)在日志文件中的地址,數(shù)據(jù)恢復(fù)時(shí)從重新開始文件找到某個(gè)檢查點(diǎn)在日志文件中的地址,并從日志中找到這個(gè)檢查點(diǎn)開始數(shù)據(jù)恢復(fù),節(jié)省了遍歷日志和重復(fù)操作的時(shí)間和資源。
檢查點(diǎn)技術(shù)對(duì)事務(wù)的恢復(fù)工作可分為以下三種情況[1]:
(1)在檢查點(diǎn)之前完成的事務(wù),更新已經(jīng)寫到數(shù)據(jù)庫(kù)中,不需要再重做;
(2)檢查點(diǎn)之后、故障點(diǎn)之前完成的事務(wù),雖然事務(wù)已結(jié)束,但它們對(duì)數(shù)據(jù)庫(kù)的修改可能還未來(lái)得及寫到磁盤上,必須要重做;
(3)故障點(diǎn)時(shí)刻尚未結(jié)束的事務(wù),它們的操作是不完整的,需要撤銷。
1.2 內(nèi)存數(shù)據(jù)庫(kù)恢復(fù)技術(shù)
內(nèi)存數(shù)據(jù)庫(kù)(MMDB)由于內(nèi)存的易失性,需要將數(shù)據(jù)持久化到磁盤,不同于普通外存數(shù)據(jù)庫(kù),MMDB需要一次性將數(shù)據(jù)全部加載到內(nèi)存,因此日志文件的大小是限制MMDB數(shù)據(jù)恢復(fù)的一個(gè)重要因素。
MMDB依然沿用了檢查點(diǎn)技術(shù),并在此基礎(chǔ)上,結(jié)合了影子內(nèi)存技術(shù)、模糊檢查點(diǎn)技術(shù)、多版本控制技術(shù)等[2,3],這些方法的共同點(diǎn)都是減少undo日志的記錄。它們將MMDB的操作在影子頁(yè)上執(zhí)行,如果事務(wù)提交,則記錄redo日志,將影子頁(yè)的操作反映到MMDB,若事務(wù)撤銷,則只需放棄影子頁(yè)即可。這樣便可以不記錄undo日志,且雙版本可以提供數(shù)據(jù)庫(kù)的動(dòng)態(tài)轉(zhuǎn)儲(chǔ)。
對(duì)于內(nèi)存數(shù)據(jù)庫(kù),數(shù)據(jù)持久化也是重要一環(huán)。梁智興通過(guò)添加非易失性內(nèi)存作為備份緩沖區(qū),提出兩步備份機(jī)制[4];周曉云利用高速局域網(wǎng)充當(dāng)內(nèi)存緩沖區(qū),提出了利用網(wǎng)絡(luò)工作站內(nèi)存加速內(nèi)存數(shù)據(jù)庫(kù)日志記錄持久化的技術(shù)方案[5]。這些都是對(duì)數(shù)據(jù)持久化的改進(jìn)。
2 Redis數(shù)據(jù)庫(kù)恢復(fù)技術(shù)概述
Redis數(shù)據(jù)庫(kù)是一種高效的內(nèi)存數(shù)據(jù)庫(kù),它的數(shù)據(jù)恢復(fù)包括兩個(gè)步驟:數(shù)據(jù)持久化和數(shù)據(jù)恢復(fù)。Redis數(shù)據(jù)庫(kù)提供兩種持久化方式, RDB和AOF[6]。數(shù)據(jù)持久化生成的文件用于Redis數(shù)據(jù)庫(kù)重啟時(shí)的數(shù)據(jù)恢復(fù)。
2.1 RDB
RDB就是Snapshot快照存儲(chǔ),是默認(rèn)的持久化方式。它按照一定的策略周期性的將數(shù)據(jù)存儲(chǔ)到磁盤,生成名為dump.rdb的文件,RDB的執(zhí)行周期可以通過(guò)配置文件中的save來(lái)配置[7]。
Redis數(shù)據(jù)庫(kù)會(huì)在達(dá)到RDB配置周期或接收到客戶端的save和bgsave命令時(shí)觸發(fā)RDB操作[8]。其中save觸發(fā)RDB操作時(shí),Redis阻塞客戶端新的請(qǐng)求,是為靜態(tài)轉(zhuǎn)儲(chǔ);而對(duì)于bgsave命令,Redis可以繼續(xù)接收處理新命令,是為動(dòng)態(tài)轉(zhuǎn)儲(chǔ)。
RDB操作借用copy on write機(jī)制進(jìn)行寫時(shí)復(fù)制[9],父進(jìn)程fork一個(gè)子進(jìn)程,由子進(jìn)程進(jìn)行內(nèi)存遍歷將數(shù)據(jù)寫入臨時(shí)文件,父進(jìn)程仍處理客戶端請(qǐng)求,待子進(jìn)程執(zhí)行完畢,將臨時(shí)文件rename為dump.rdb,因此無(wú)論RDB是否成功,dump.rdb都是完整的。
dump.rdb是一種緊湊的二進(jìn)制文件,文件很小利于備份,也常用于主從復(fù)制。RDB方式恢復(fù)速度快,但周期性的特點(diǎn)注定不能恢復(fù)兩個(gè)周期之間的數(shù)據(jù)。
2.2 AOF
AOF是一種追加性日志文件,Redis數(shù)據(jù)庫(kù)會(huì)將收到的所有寫命令按AOF文件協(xié)議順序追加到AOF文件中,因此AOF比RDB方式有更好的持久化性。在數(shù)據(jù)恢復(fù)時(shí),Redis數(shù)據(jù)庫(kù)通過(guò)重新執(zhí)行AOF文件中保存的寫命令,在內(nèi)存中重建整個(gè)數(shù)據(jù)庫(kù)的內(nèi)容。
AOF可以通過(guò)在配置文件中設(shè)置appendonly為yes/no來(lái)開啟或關(guān)閉,還可以設(shè)置fsync為no/everysec/always來(lái)改變同步策略為關(guān)閉或每秒同步或每個(gè)寫操作同步。
AOF操作生成appendonly.aof,這是一種文本文件,按AOF協(xié)議記錄所有寫操作[10]。日志不斷追加,文件會(huì)越來(lái)越大,Redis提供了AOF重寫機(jī)制。AOF重寫在appendonly.aof增長(zhǎng)到設(shè)定值或接收到bgrewriteaof命令時(shí)觸發(fā)。
AOF重寫由父進(jìn)程fork一個(gè)子進(jìn)程,子進(jìn)程遍歷數(shù)據(jù)庫(kù)內(nèi)存并將數(shù)據(jù)記錄到臨時(shí)文件,父進(jìn)程繼續(xù)接收客戶端請(qǐng)求,將后續(xù)寫操作追加到appendonly.aof和AOF重寫緩存,待子進(jìn)程執(zhí)行完畢,將緩存內(nèi)容追加到臨時(shí)文件,并rename為appendonly.aof完成重寫操作[11]。
AOF可以記錄所有寫操作,恢復(fù)時(shí)可以恢復(fù)全部數(shù)據(jù),但日志文件體積較大,且恢復(fù)時(shí)需模擬客戶端重新執(zhí)行日志所記錄的操作,恢復(fù)速度較慢。
3 RDB+AOF的恢復(fù)方案
RDB恢復(fù)數(shù)據(jù)不完整,AOF恢復(fù)速度慢,為了解決這兩大問(wèn)題,本文提出了RDB+AOF的方案。
3.1 方案簡(jiǎn)介
RDB+AOF組合方案是指Redis同時(shí)開啟RDB和AOF選項(xiàng),以AOF為主記錄日志,當(dāng)日志文件達(dá)到閾值觸發(fā)AOF重寫時(shí),不再使用原有的重寫機(jī)制,而讓Redis服務(wù)fork一個(gè)子進(jìn)程執(zhí)行RDB操作,生成一個(gè)臨時(shí)RDB文件,主進(jìn)程依然接受客戶端請(qǐng)求,并將命令寫入AOF文件和一個(gè)臨時(shí)AOF文件中,待子進(jìn)程結(jié)束,將新生成的RDB臨時(shí)文件rename為dump.rdb,而將臨時(shí)AOF文件rename為appendonlyfile.aof,至此一次RDB+AOF組合的持久化就完成了。
持久化生成的RDB和AOF文件都將用來(lái)進(jìn)行數(shù)據(jù)恢復(fù),恢復(fù)策略是首先Redis數(shù)據(jù)庫(kù)加載RDB文件,將數(shù)據(jù)庫(kù)恢復(fù)到最新一次快照時(shí)的狀態(tài),然后模擬客戶端,將AOF文件中的命令執(zhí)行一遍,使數(shù)據(jù)庫(kù)恢復(fù)到上次關(guān)機(jī)或故障時(shí)的狀態(tài),這樣數(shù)據(jù)庫(kù)的恢復(fù)就完成了。
RDB+AOF方案的具體執(zhí)行流程如圖1:
3.2 方案原理
要結(jié)合RDB和AOF兩種方案,需要分析一下RDB+AOF的可行性。
(1)基于命令執(zhí)行的數(shù)量觸發(fā)
RDB依據(jù)配置在一定時(shí)間內(nèi)完成一定的命令就會(huì)觸發(fā),例如60秒內(nèi)修改了10000條記錄;而AOF是按AOF協(xié)議將命令記錄到日志文件,在文件大小達(dá)到閾值時(shí)觸發(fā)重寫,本質(zhì)也是完成一定的命令導(dǎo)致AOF重寫。
根據(jù)Redis命令的原子性,RDB和AOF重寫都將在完成命令的時(shí)刻執(zhí)行,因此執(zhí)行時(shí)不會(huì)有執(zhí)行一半的命令,保證了文件的完整性,也為RDB+AOF相結(jié)合提供了保障。
(2)copy on write機(jī)制
Copy on write機(jī)制是父子進(jìn)程共享同一物理內(nèi)存,即子進(jìn)程借用父進(jìn)程的內(nèi)存做遍歷操作,若此時(shí)父進(jìn)程接收到寫命令,父進(jìn)程會(huì)為寫命令影響到的內(nèi)存數(shù)據(jù)開辟新內(nèi)存,寫命令所造成的臟數(shù)據(jù)只會(huì)影響到這塊新開辟的內(nèi)存,子進(jìn)程使用的依舊是RDB或AOF重寫開始時(shí)的內(nèi)存空間,這種寫時(shí)復(fù)制機(jī)制完美解決了動(dòng)態(tài)復(fù)制的問(wèn)題。
RDB和AOF重寫都使用copy on write機(jī)制,這為RDB+AOF方案中用RDB代替AOF重寫提供了保障。
(3)非事務(wù)一致性
Redis雖然提供簡(jiǎn)單的事務(wù)支持,但并不提供回滾功能,也就是不保證事務(wù)一致性,因此日志并不需要記錄undo日志。因此RDB和AOF文件本質(zhì)都是數(shù)據(jù)的映像,沒(méi)有什么區(qū)別,為RDB+AOF方案提供了便利條件。
(4)日志的追加性
日志文件是按時(shí)間追加的,在RDB+AOF方案中,檢查點(diǎn)之前的日志對(duì)數(shù)據(jù)恢復(fù)已經(jīng)沒(méi)有作用,可以刪掉減小文件體積,這就是用AOF臨時(shí)文件覆蓋原文件對(duì)理論支持。
3.3 對(duì)照試驗(yàn)
本次實(shí)驗(yàn)有三個(gè)目標(biāo):數(shù)據(jù)持久化速度、數(shù)據(jù)恢復(fù)速度和數(shù)據(jù)恢復(fù)完整性。
本實(shí)驗(yàn)的實(shí)驗(yàn)環(huán)境為Mac OS X 10.11.1系統(tǒng),2.7 GHz Intel Core i5處理器,8G內(nèi)存以及Redis3.0.7。
3.3.1 數(shù)據(jù)持久化速度
數(shù)據(jù)持久化速度以寫入相同數(shù)據(jù)量所用時(shí)間來(lái)計(jì)算。如圖2為分別寫入100、10000、100000、1000000條數(shù)據(jù)時(shí)RDB、AOF以及RDB+AOF三種方案的耗時(shí)情況。
圖2中AOF方式的同步策略為每秒同步,由圖中可以看出每秒同步的AOF方式與RDB方式在持久化方面性能相差不大,而RDB+AOF方案是以AOF為主要持久化方案,只在AOF重寫時(shí)由RDB代替,因而性能接近AOF方式。
3.3.2 數(shù)據(jù)恢復(fù)速度
數(shù)據(jù)恢復(fù)速度以加載相同數(shù)據(jù)量所用時(shí)間來(lái)表示。對(duì)數(shù)據(jù)持久化所得文件進(jìn)行加載,得到三種方式加載時(shí)間的對(duì)比,如圖3所示:
從圖中可以看出,三種方式數(shù)據(jù)恢復(fù)速度相差很大,AOF方式恢復(fù)速度是RDB方式的2倍左右,而RDB+AOF方式恢復(fù)速度介于兩者之間。
比較RDB和AOF兩種方式對(duì)相同數(shù)據(jù)持久化產(chǎn)生的文件大小,如表1所示:
表中所示AOF文件是RDB文件的2倍左右,這也可以解釋為何AOF方式恢復(fù)時(shí)間是RDB方式的2倍。
而RDB+AOF方式的恢復(fù)速度介于兩者之間,具體情況如表2所示:
從表2中可以看出,RDB+AOF方式隨著RDB和AOF文件大小的比例在變化,在RDB+AOF方案中,隨著AOF重寫,數(shù)據(jù)不斷從AOF文件轉(zhuǎn)移到RDB文件,它的恢復(fù)時(shí)間也從AOF方式向RDB方式的方向不斷減少,理想狀態(tài)下將達(dá)到RDB方式的恢復(fù)速度。
3.3.3 數(shù)據(jù)恢復(fù)完整性
數(shù)據(jù)恢復(fù)完整性以恢復(fù)的數(shù)據(jù)量為準(zhǔn)。對(duì)三種方案分別寫入5條新數(shù)據(jù),然后kill掉Redis服務(wù),重啟服務(wù)后檢查新數(shù)據(jù)的恢復(fù)情況,如表3所示:
從表中可以看出,RDB+AOF方案完美繼承了AOF恢復(fù)數(shù)據(jù)完整性的優(yōu)點(diǎn)。
4 結(jié)論
本文借鑒檢查點(diǎn)恢復(fù)方法的思想,在Redis數(shù)據(jù)庫(kù)中,巧妙地結(jié)合了RDB和AOF兩種方法,利用AOF日志完整記錄數(shù)據(jù)庫(kù)操作,又通過(guò)RDB代替AOF重寫,利用RDB文件恢復(fù)速度快的特性減少了恢復(fù)時(shí)間。RDB+AOF恢復(fù)方案,能夠在完整恢復(fù)數(shù)據(jù)庫(kù)的前提下提高恢復(fù)速度,在持久化時(shí),數(shù)據(jù)會(huì)隨AOF重寫從AOF文件轉(zhuǎn)移到RDB文件,理想情況下可以達(dá)到RDB的恢復(fù)速度。但重寫本身也是一個(gè)耗時(shí)操作,數(shù)據(jù)持久化需要和數(shù)據(jù)恢復(fù)達(dá)到平衡,才能達(dá)到最合適的用戶體驗(yàn),這將是進(jìn)一步的研究方向。
參考文獻(xiàn):
[1] 周如意. 基于檢查點(diǎn)的數(shù)據(jù)庫(kù)恢復(fù)技術(shù)[J]. 沙洲職業(yè)工學(xué)院學(xué)報(bào), 2006(2):11-14.
[2] 黃琳, 路京, 林中. 基于影子頁(yè)面的MMDB的數(shù)據(jù)恢復(fù)方法[J]. 計(jì)算機(jī)工程與設(shè)計(jì), 2008, 29(10):2470-2473.
[3] 杜曄. 空間實(shí)時(shí)內(nèi)存數(shù)據(jù)庫(kù)恢復(fù)機(jī)制研究與實(shí)現(xiàn)[D]. 中國(guó)科學(xué)院研究生院, 2012.
[4] 梁智興, 羅軍. 基于兩步備份機(jī)制的內(nèi)存數(shù)據(jù)庫(kù)恢復(fù)方法研究[J]. 網(wǎng)絡(luò)安全技術(shù)與應(yīng)用, 2010(1):24-27.
[5] 周曉云, 覃雄派. 基于網(wǎng)絡(luò)內(nèi)存的內(nèi)存數(shù)據(jù)庫(kù)高效恢復(fù)技術(shù)[J]. 系統(tǒng)工程理論與實(shí)踐, 2011, 系統(tǒng)工程理論與實(shí)踐, 2011, 31(增刊2):81-87(S2):81-87.
[6] 馬豫星. Redis數(shù)據(jù)庫(kù)特性分析[J]. 物聯(lián)網(wǎng)技術(shù), 2015(3):105-106.
[7] Hey! Linux. Redis持久化實(shí)踐及災(zāi)難恢復(fù)模擬[EB/OL]. http://heylinux.com/archives/1932.html, 2012-09-27.
[8] 常飛夢(mèng). 驗(yàn)證redis的快照和AOF[EB/OL]. http://blog.csdn.net/lichangzai/article/details/8692103, 2013-03-19.
[9] 婁振林專欄. redis源碼分析(7)——rdb[EB/OL]. http://blog.csdn.net/chosen0ne/article/details/44650847/, 2015-04-15.
[10] 婁振林專欄. redis源碼分析(5)——aof[EB/OL]. http://blog.csdn.net/chosen0ne/article/details/44035453/, 2015-03-17.
[11] 婁振林專欄. redis源碼分析(6)——aof rewrite[EB/OL]. http://blog.csdn.net/chosen0ne/article/details/44461497/, 2015-03-23.