同樣是持久化,竟然有這麼大的差別!

  • 2020 年 11 月 3 日
  • 筆記

作為內存數據庫,Redis 在數據存儲與讀取上的速度是毫不遜色的,這點毋庸置疑。但是對於內存來說,斷電或遇到故障後數據就會丟失,這卻是一個無法迴避的問題。令人欣慰的是,基於這樣的缺點,Redis 也提供了不同的持久化方案。

各位看官請隨小萊接着往下看: 

圖註:思維導圖

RDB持久化

對於 Redis 持久化來說,其實就是將存儲在內存中的數據寫入到磁盤裡,只不過寫入的方式是有一定策略的。

那麼我們先來看下第一種持久化,首先出場的是 RDB。 

1、什麼是RDB持久化

英文名稱是 Redis DataBase,它還有一個常用的名字:快照持久化。所謂快照,在這裡指的是某一時刻的內存數據,而持久化則是將這一時刻的數據以二進制形式寫入到磁盤裡。

 2、手動觸發機制

(1)save 命令

你可能會問了,那我通過什麼樣的方式來實現持久化呢?不知道你有沒有用過 save 這個命令,在 Redis 里擔任的角色是用來手動觸發持久化的。也就是說在 Redis 客戶端操作 save 命令就可以將內存數據寫入到磁盤裡。

不過你可千萬不要好奇,生產環境要是這麼玩兒的話,數據量少還行,數量大的話那估計八成得涼涼。為什麼這麼說呢?你稍微了解下它的運行原理就知道了。

前面的文章中,我們提到了 Redis 處理命令的方式是以單線程形式來進行的。客戶端的請求都會放入一個隊列里。當執行 save 命令時,如果執行時間很長的話,後面的請求就會被阻塞,客戶端發送的所有命令都會被拒絕。

這種方式生產場景要慎用!

(2)bgsave 命令

還有一個 bgsave 命令。與 save 不同的是,執行過程中它並不會阻塞客戶端的請求。而是將持久化工作交給子進程來執行,主進程仍負責客戶端請求的處理工作。  

3、自動觸發機制

RDB 持久化既可以通過手動觸發,也可以通過服務器配置項來定期執行。

自動觸發通常是 Redis 中配置文件來執行的。有這麼個配置你需要了解下:

save m n

其中 m 代表秒數,n 代表次數,放在一起表示的是 m 秒內發生 n 次變化時,會觸發 bgsave。

了解了自動化配置,我們再來看下 Redis 配置文件 redis.conf 中的三個默認配置項:

save 900 1 表示的是時間900秒內,如果 Redis 中數據至少發生一次變化,就會執行 bgsave。後邊兩個就不用介紹了,一樣的原理。 

看到這三個配置項,不知道你會不會有疑問,這三個到底該執行哪一個?答案是設置多個 save m n 命令時,滿足任何一個條件都會觸發持久化。

4、RDB 文件恢復

前面我們提到過了,持久化的目的就是為了解決內存異常導致的數據丟失問題。那麼倘若如果真遇到了這樣的情況,RDB 文件如何來實現數據恢復呢?

開啟自動持久化後,數據會存儲到名為 dump.rdb 的文件中。當 Redis 服務器重啟時,檢測到 dump.rdb 文件後,會自動加載進行數據恢復。

AOF持久化

介紹完了 RDB 後,我們再來看一種叫作 AOF 的持久化方式。

1、什麼是AOF持久化

英文名稱是 Append Only File。同樣地,它也有一個常用的名字:文件追加持久化。與RDB 不同的是,它是通過保存所執行的寫命令來實現的,並且保存的數據格式是客戶端發送的命令。

 

2、AOF 實現方式 

想要使用 AOF 持久化方式,需要啟用配置文件中的 appendonly 參數。默認情況下,Redis 是不開啟的。

 

 開啟 AOF 持久化後每執行一條修改數據的命令,Redis 就會將該命令寫入 aof_buf 緩衝區。後續寫入 AOF 文件中的操作是由下面的配置來控制的:

 

這三個配置項分別表示:

appendfsync always:每次寫入都進行刷盤操作,對性能影響最大,佔用磁盤 IO 較高,數據安全性最高。 

appendfsync everysec:1秒刷一次盤,對性能影響相對較小。

appendfsync no:按照操作系統的機制進行刷盤,對性能影響最小,數據安全性低。

3、AOF 重寫機制

隨着命令的不斷寫入,AOF 文件會變得越來越大,這時候該如何是好呢?別急,Redis 中提供了瘦身功能,也就是重寫機制。

Redis 配置文件中有兩個對應的參數是來決定重寫機制的觸發時機的。

auto-aof-rewrite-percentage:AOF 文件距離上次文件增長超過多少百分比

auto-aof-rewrite-min-size:AOF 文件體積最小多大以上觸發

滿足所設置的條件時,會自動觸發 AOF 重寫,此時 Redis 會掃描整個實例的數據,重新生成一個 AOF 文件來達到瘦身的效果。

4、AOF 文件恢復

同樣地,我們也需要對 AOF 文件進行恢復。和 RBD 不同的是,Redis 中是通過創建一個不帶網絡連接的偽客戶端來進行實現的。為什麼要創建偽客戶端呢?你想想 AOF 文件中的數據格式,都是由命令組成的。通過客戶端直接執行每條命令就可以將數據進行恢復。

在這裡需要注意的是,如果服務器開啟了 AOF 持久化功能,會優先使用 AOF 文件來進行恢復。只有在 AOF 關閉狀態下,服務器才會使用 RDB 文件來進行還原。

兩種持久化的優/缺點

到這裡,對兩種持久化也有了一定的認識,那麼我們來看看它們分別有什麼優點和缺點:

1、RDB 優點與缺點

(1)優點

文件體積小:RDB 的文件內容是二進制格式,因此體積比實例內存小。恢復速度快:當 Redis 實例恢復時,加載 RDB 文件速度很快,能在很短時間內迅速恢複數據。

(2)缺點

數據缺失:RDB 保存的是某一時刻的數據,當 Redis 實例某一時刻異常時,會導致數據丟失。消耗資源:RDB 文件的生成會消耗大量的 CPU 和內存資源,有一定代價。

2、AOF 優點與缺點

(1)優點

數據更完整:AOF 中是及時寫入的方式,數據保存更完整。恢復時降低數據的損失率

易讀性強:AOF 中保存的數據格式是客戶端的寫入命令,可讀性性強。

(2)缺點

文件體積大:AOF 中存儲客戶端所有的寫命令,未經壓縮,隨着命令的寫入,文件會越來越大。增加磁盤IO:AOF 文件刷盤如果採用每秒刷一次的方式會導致磁盤IO升高,影響性能。

混合持久化

既然 RDB 與 AOF 持久化都存在各自的缺點,那麼有沒有一種更好的持久化方式?

接下來要介紹的是混合持久化。其實就是 RDB 與 AOF 的混合模式,這是 Redis4 之後新增的。

1、持久化方式

混合持久化是通過 aof-use-rdb-preamble 參數來開啟的。它的操作方式是這樣的,在寫入的時候先把數據以 RDB 的形式寫入文件的開頭,再將後續的寫命令以 AOF 的格式追加到文件中。這樣既能保證數據恢復時的速度,同時又能減少數據丟失的風險。

2、文件恢復

那麼混合持久化中是如何來進行數據恢復的呢?在 Redis 重啟時,先加載 RDB 的內容,然後再重放增量 AOF 格式命令。這樣就避免了 AOF 持久化時的全量加載,從而使加載速率得到大幅提升。

總結

RDB持久化

  • 將某一時刻的數據以二進制形式寫入到磁盤裡,服務重啟時檢測到對應文件自動加載進行數據恢復。

  • 有手動觸發和自動觸發兩種機制。

AOF持久化

  • 以文件追加的方式寫入客戶端執行的寫命令。

  • 數據恢復時,通過創建偽客戶端的方式執行命令,直到恢復完成。

混合持久化

    • 在寫入的時候先把數據以 RDB 的形式寫入文件的開頭,再將後續的寫命令以 AOF 的格式追加到文件中。

關於作者

作者:大家好,我是萊烏,BAT搬磚工一枚。從小公司進入大廠,一路走來收穫良多,想將這些經驗分享給有需要的人,因此創建了公眾號「IT界農民工」。定時更新,希望能幫助到你