溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

進階的Redis之數(shù)據(jù)持久化RDB與AOF

發(fā)布時間:2020-06-18 07:48:07 來源:網(wǎng)絡 閱讀:299 作者:Zack說碼 欄目:關系型數(shù)據(jù)庫

大家都知道,Redis之所以性能好,讀寫快,是因為Redis是一個內(nèi)存數(shù)據(jù)庫,它的操作都幾乎基于內(nèi)存。但是內(nèi)存型數(shù)據(jù)庫有一個很大的弊端,就是當數(shù)據(jù)庫進程崩潰或系統(tǒng)重啟的時候,如果內(nèi)存數(shù)據(jù)不保存的話,里面的數(shù)據(jù)就會丟失不見了。這樣的數(shù)據(jù)庫并不是一個可靠的數(shù)據(jù)庫。

所以數(shù)據(jù)的持久化是內(nèi)存型數(shù)據(jù)庫的重中之重。它不僅提供數(shù)據(jù)保存硬盤的功能,還可以借此用硬盤容量擴展數(shù)據(jù)存儲空間,使得Redis的可以存儲超過機器本身內(nèi)存大小的數(shù)據(jù)。

Redis對于數(shù)據(jù)持久化提供了兩種持久化的方案,RDB與AOF。它們的原理和使用場景都大不相同,下面我們來詳細地了解下。

RDB——數(shù)據(jù)快照(Snapshot)

RDB,提供一個某個時間點的數(shù)據(jù)的Snapshot,保存在RDB文件中。它可以通過SAVE/BGSAVE命令手動執(zhí)行,把數(shù)據(jù)Snapshot寫到RDB文件,也可以通過配置,定時執(zhí)行。

Redis也可以通過加載RDB文件,把數(shù)據(jù)從磁盤加載讀取到Redis中。

RDB文件創(chuàng)建

連上Redis,設值一些值,然后執(zhí)行SAVE命令。
進階的Redis之數(shù)據(jù)持久化RDB與AOF

然后可以查看下redis.conf的持久化工作目錄。進入目錄可以看到保存了一個dump.rdb文件。該文件是一個二進制文件,無法直接正常打開。
進階的Redis之數(shù)據(jù)持久化RDB與AOF

至于SAVE/BGSAVE的區(qū)別,就是前置是阻塞執(zhí)行,此時服務不會接受請求,后者是Fork一個子進程出來,由該進程去執(zhí)行保存RDB文件的操作,不影響用戶請求。

P.S. Redis是單進程的,所以BGSAVE只能Fork一個子進程,而不是創(chuàng)建一個線程處理。

以上是手動執(zhí)行的過程。但在生產(chǎn)我們很少會手動登上服務去執(zhí)行操作,所以更多的時候是依賴Redis的配置,定時保存RDB文件。

打開redis.conf配置文件,找到SNAPSHOTTING的配置,Save Point的設置。
進階的Redis之數(shù)據(jù)持久化RDB與AOF
圖中的配置意思是,當至少有一個key變更時,900秒后會執(zhí)行一次SAVE。其他配置同理,有10次變更,300秒后保存一次.....

在Redis中,這個自動保存RDB的功能是默認開啟的。

RDB文件加載

先kill掉Redis進程,再重新啟動Redis Server,會發(fā)現(xiàn)日志會有這樣的一行,
進階的Redis之數(shù)據(jù)持久化RDB與AOF

并且Redis中,依然有之前設置的三個值。說明Redis在啟動的時候,會加載數(shù)據(jù)初始化。

不過,這里加載的初始化數(shù)據(jù)不一定是RDB的。如果Redis開啟了AOF,會優(yōu)先從AOF初始化數(shù)據(jù),否則才會加載RDB的數(shù)據(jù)。

RDB優(yōu)缺點

優(yōu)點:

  1. RDB是某一時間點的快照,是一個緊湊的單文件,更多用于數(shù)據(jù)備份??梢园疵啃r或每日來備份,方便從不同的版本恢復數(shù)據(jù)。
  2. 單文件容易傳輸?shù)竭h程服務做故障恢復。
  3. RDB可以Fork子進程進行持久化,使Redis可以更好地處理用戶請求
  4. 在大量數(shù)據(jù)的情況下,RDB相比較于AOF會更快的加載。

缺點:

  1. 如果Redis不及時保存RDB文件,會造成數(shù)據(jù)的丟失。例如系統(tǒng)突然斷電,但未來得及保存數(shù)據(jù)。即使你設置更多的Save point,也無法保證100%的數(shù)據(jù)不丟失。
  2. RDB經(jīng)常需要fork子進程去執(zhí)行,但如果再大量數(shù)據(jù)的情況下,這個fork操作會非常耗CPU資源的。對比AOF雖然也是fork,但是它的數(shù)據(jù)保存處理是可以控制的,不需要全量保存。

AOF——日志追加(Append-Only)

Redis的另外一種持久化方案就是AOF,Append Only File。AOF相當于一個操作的日志記錄,每次對于數(shù)據(jù)的變更都會記錄追加到AOF日志。當服務啟動的時候就會讀這些操作日志,重新執(zhí)行一次操作,從而恢復原始數(shù)據(jù)。

AOF啟用

AOF默認是關閉的。打開redis.conf配置文件,找到appendonly no改成appendonly yes。
進階的Redis之數(shù)據(jù)持久化RDB與AOF
AOF和RDB是可以共存的,只要保存的文件名不沖突。

AOF fsync同步規(guī)則

配置文件往下拉,看到fsync的配置。
進階的Redis之數(shù)據(jù)持久化RDB與AOF
fsync()是一個系統(tǒng)調(diào)用函數(shù),告訴操作系統(tǒng)把數(shù)據(jù)寫到硬盤上,而不是緩存更多數(shù)據(jù)才寫到硬盤。這樣的調(diào)用可以及時保存數(shù)據(jù)到硬盤上。

Redis提供了三種fsync的調(diào)用方式

  • appendfsync always,每次操作記錄都同步到硬盤上,最低效,最安全。
  • appendfsync everysec,每秒執(zhí)行一次把操作記錄同步到硬盤上。默認選項。
  • appendfsync no,不執(zhí)行fysnc調(diào)用,讓操作系統(tǒng)自動操作把緩存數(shù)據(jù)寫到硬盤上,不可靠,但最快。

AOF文件格式解析

開啟AOF后,會再工作目錄看到appendonly.aof文件。
進階的Redis之數(shù)據(jù)持久化RDB與AOF
在客戶端上執(zhí)行一些命令后,打開AOF文件,可以觀察到有對應的操作的記錄日志。
進階的Redis之數(shù)據(jù)持久化RDB與AOF
文件解析說明:

  • *,表示命令的參數(shù)個數(shù),例如set a 1是三個參數(shù),所以是*3
  • $,表示參數(shù)的字節(jié)數(shù),例如set這個參數(shù)是三字節(jié),所以是$3,key值a是一個字節(jié),所以是$1
  • 無符號,表示是參數(shù)的數(shù)據(jù),例如set,a,1就是具體的數(shù)據(jù)

日志重寫

AOF雖然比RDB更可靠,但缺點也是比較明顯的,就是每次寫操作都要把操作日志寫到文件上,這樣會導致文件非常冗余。

假若你要自增一個計數(shù)器100次,如果不重寫,AOF文件就就會有這100次的自增記錄,如INCR a。如果執(zhí)行了日志重寫,那么文件只會保留set a 100而不是100條INCR a。這樣擁有相同的結果,但可以大大減少AOF的文件大小,并且可以讓AOF載入的時候提升載入的效率。

看回redis.conf配置,有兩項控制rewrite的選項。
進階的Redis之數(shù)據(jù)持久化RDB與AOF

  • auto-aof-rewrite-percentage 100,當文件增長100%(一倍)時候,自動重寫。
  • auto-aof-rewrite-min-size 64mb,日志重寫最小文件大小,如果小于該大小,不會自動重寫。

來實驗一下重寫的結果,我們先設定一個a值,然后自增多次,查看AOF文件內(nèi)容。里面有很多INCR的語句記錄
進階的Redis之數(shù)據(jù)持久化RDB與AOF

然后我們手動執(zhí)行下BGREWRITEOF,執(zhí)行日志重寫。
進階的Redis之數(shù)據(jù)持久化RDB與AOF
可以看到,多個incr語句,變成了一個set a 6語句,減少了5個incr a語句的操作日志。

AOF優(yōu)缺點

優(yōu)點:

  1. AOF可以設置 完全不同步、每秒同步、每次操作同,默認是每秒同步。因為AOF是操作指令的追加,所以可以頻繁的大量的同步。
  2. AOF文件是一個值追加日志的文件,即使服務宕機為寫入完整的命令,也可以通過redis-check-aof工具修復這些問題。
  3. 如果AOF文件過大,Redis會在后臺自動地重寫AOF文件。重寫后會使AOF文件壓縮到最小所需的指令集。
  4. AOF文件是有序保存數(shù)據(jù)庫的所有寫入操作,易讀,易分析。即使如果不小心誤操作數(shù)據(jù)庫,也很容易找出錯誤指令,恢復到某個數(shù)據(jù)節(jié)點。例如不小心FLUSHALL,可以非常容易恢復到執(zhí)行命令之前。

缺點

  1. 相同數(shù)據(jù)量下,AOF的文件通常體積會比RDB大。因為AOF是存指令的,而RDB是所有指令的結果快照。但AOF在日志重寫后會壓縮一些空間。
  2. 在大量寫入和載入的時候,AOF的效率會比RDB低。因為大量寫入,AOF會執(zhí)行更多的保存命令,載入的時候也需要大量的重執(zhí)行命令來得到最后的結果。RDB對此更有優(yōu)勢。

如何選擇

以上已經(jīng)基本了解過RDB和AOF的使用、基本原理以及對應的優(yōu)缺點。那么在實際當中,我們到底怎么去選擇用哪種持久化方式呢?

一般來說,不考慮硬盤大小,最安全的做法是RDB與AOF同時使用,即使AOF損壞無法修復,還可以用RDB來恢復數(shù)據(jù)。

如果Redis的數(shù)據(jù)在你的服務中并不是必要的數(shù)據(jù),例如只是當簡單的緩存,沒有緩存也不會造成緩存雪崩。說明數(shù)據(jù)的安全可靠性并不是首要考慮范圍內(nèi),那么單獨只使用RDB就可以了。

不推薦單獨使用AOF,因為AOF對于數(shù)據(jù)的恢復載入來說,比RDB慢。并且Redis官方也說明了,AOF有一個罕見的bug。出了問題無法很好的解決。所以使用AOF的時候,最好還是有RDB作為數(shù)據(jù)備份。

進階的Redis之數(shù)據(jù)持久化RDB與AOF
根據(jù)官方的意愿描述,在未來可能會有一種RDB與AOF相結合的持久化模型。到時Redis持久化就不再如此麻煩費勁了,我們拭目以待吧。


更多技術文章、精彩干貨,請關注
博客:zackku.com
微信公眾號:Zack說碼
進階的Redis之數(shù)據(jù)持久化RDB與AOF

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內(nèi)容。

AI