教你如何讓Redis更持久 !

蔡不菜丶發表於2021-09-28

大家好,我是小菜。
一個希望能夠成為 吹著牛X談架構 的男人!如果你也想成為我想成為的人,不然點個關注做個伴,讓小菜不再孤單!

本文主要介紹 Redis 的持久化

如有需要,可以參考

如有幫助,不忘 點贊

微信公眾號已開啟,小菜良記,沒關注的同學們記得關注哦!

最近在面試的路上愈走愈遠了,Redis肯定是一個熱門面試方向。像有幾種資料結構?如何實現延遲佇列?淘汰機制是怎麼樣的?都快問到麻木,這些問題還常繞腦樑。那我們這篇就舉一個比較常見且難度適中的面試題來聊聊。Redis 的持久化策略是怎麼樣的?

開局問個問題,相信被問到 Redis 持久化 的同學肯定不在少數,答對的同學肯定也不在少數,有些小夥伴說到 Redis持久化 肯定張口就來,畢竟也就 AOF 和 RDB 兩個概念,只要你準備了面試,就不會被問的太慘。但是你是真的懂還是隻是為了應付面試而去應付記憶?你知道 AOFRDB 兩個詞是什麼單詞的縮寫嗎?你落地實施過嗎?你真以為面試官聽不出來你是背題還是實操嗎?如果 4 個問題你中了一半,那不妨往下看看,也許會有些收穫,起碼答面試題的時候心中有小菜~!

Redis 持久化

什麼是Redis持久化?

我們們先別記得往解決方向前行,先明白這道題的意思。

持久化 就是要讓資料永久的儲存下去。那什麼是 Redis 持久化 ?那就是把Redis儲存在記憶體的資料寫到磁碟中,防止服務當機了記憶體資料丟失問題。那有些小夥伴就說了,那磁碟損壞了,資料怎麼持久化?就算多點備份能解決磁碟損壞問題,那如果來個多點丟失怎麼整?停住停住,我們們這篇講的是Redis記憶體資料->磁碟的持久化問題,可別指望靠這個問題跟面試官扯半個小時~!

我們們這篇從幾個點來說明 Redis持久化 問題。

也就三點大的方向,三步走戰略解決你的持久化問題。

一、RDB

先來解決開局的問題之一,RDB 是什麼單詞的全稱。 RDB(Redis Database Backup file)--- Redis 資料備份檔案,也稱為 Redis 資料快照。

這個玩意就是用來將記憶體中的所有資料都記錄到磁碟中,當 Redis 例項故障重啟後,從磁碟讀取快照檔案,從而恢復資料。內心狂喜,看來學的第一個概念就可以解決 Redis 持久化問題~

在學 RDB 之前,我們先明白兩個核心概念 forkcow,下面我們會解釋,這裡先賣個關子。

RDB 是 Redis 中預設的持久化機制,按照一定的時間將記憶體中的資料以快照的方式儲存到磁碟中,它會產生一個特殊型別的檔案 .rdb 資料檔案,同時可以通過配置檔案中的 save 引數來定義快照的週期.

我們從配置檔案中的兩個配置引數入手,首先是 save 配置。

這個指令是由 Redis 主程式來執行RDB,會阻塞所有命令

image-20210914183245450

我們在配置檔案中找到有關於 sava 的配置

1、

dbfilename dump.rdb

該配置項的作用便是用來定義 rdb 檔名(需要注意該名稱不能定義為路徑,只能定義為檔名稱)

當我們執行完 save 命令後,便可在 redis 資料夾中看到一個 dump.rdb 檔案

2、

save <seconds> <changes>

該配置項的作用是用來定義多長時間內發生多少次變化便會執行 bgsave,如果是 save "" 則表示禁用 RDB

我們接下來開啟 save 配置進行測試

dbfilename dump-test.rdb  # 檔名為 dump-test.rdb
save 3600 1     # 在 3600 秒內發生一次更改,便會執行 bgsave

我們通過 redis-cli 進入操作

image-20210914201037760

然後我們退出後便可在當前目錄下看到剛剛生成的 dump-test.rdb 檔案

說明我們配置是生效的,接著我們直接重啟 Redis ,看是否還存在我們剛剛儲存的資料

看到我們的資料,就說明 redis 持久化成功了。然後我們把剛剛生成的 dump-test.rdb 檔案刪除後重啟 redis

image-20210914201528245

這可以說明Redis 啟動時是靠 .rdb 來恢復檔案資料的。那我們上面一直說到的 bgsave,那 bgsave 又是如何執行的呢?

我們在前面有說過兩個概念 forkcow,不知道是否還有印象,這兩個概念便是關鍵~!

bgsave 開始的時候會 fork 主程式得到一個新的子程式,而 子程式共享 主程式的記憶體資料的。子程式會將資料寫到磁碟上的一個臨時的 .rdb 檔案中,當子程式寫完臨時檔案後,會將原來的 .rdb檔案替換掉。這個就是 fork 的核心,那什麼是 cow 呢? cow 全稱 copy-on-write 技術,當主程式執行讀操作的時候是訪問共享記憶體的,而主程式執行寫操作的時候,則會拷貝一份資料,執行寫操作。

具體流程如下:

這種持久化方式有什麼優點呢?

  • 方便持久化,只有一個 dump.rdb 檔案
  • 容災性好,可以將檔案儲存到安全的磁碟中
  • 效能最大化,fork 子程式來完成寫操作,讓主程式繼續處理命令,將 IO 最大化,保證 Redis 的高效能

缺點也是有的:

  • 資料安全性低,RDB 是間隔一段時間來持久化 (save <seconds> <change>) ,如果持久化期間 Redis 發生故障,那麼就會造成資料丟失,所以這種方式適用於資料要求不是很嚴謹的情況下使用
  • 儲存時間長,如果資料量很大,儲存快照的時間就會很長,會佔用磁碟空間

優劣均沾,斟酌使用

二、AOF

AOF 全稱 Append Only File (追加檔案)。作用便是 Redis 處理的每一個寫命令都會記錄在 AOF 檔案中,可以看做是命令日誌檔案。

該功能預設是關閉的,我們可以在 redis.conf 檔案中檢視有關於 AOF 相關的配置項

1、

appendonly yes   # 開啟 AOF 日誌記錄功能,預設是關閉的

2、

appendfilename "appendonly.aof"  # AOF 檔案的名稱

以上兩個配置項便是用來開啟 AOF 日誌記錄,那麼還有個額外的配置項也需要了解

3、

appendfsync everysec   # AOF 命令記錄的頻率

該配置項有三個可選值

配置項刷盤時機優點缺點
Always同步刷盤可靠性高,幾乎不會丟失資料效能影響較大
everysec每秒刷盤效能適中最多丟失1秒的資料
no作業系統控制效能最好可靠性較差,可能丟失大量的資料

有了解 Mysqlrelay log 日誌的同學,就不會對這種模型很陌生。

原理:它是將寫命令追加到 AOF 檔案的末尾,使用 AOF 持久化需要設定同步選項,從而確保寫命令同步到磁碟檔案上的時機,這是因為對檔案進行寫入並不會馬上將記憶體同步到磁碟上,而是先儲存到快取區中,然後由作業系統決定什麼時候同步到磁碟。

我們開啟 AOF 記錄功能檢視下:

可以看出我們的每一個操作都已經記錄到 AOF 檔案中,我們這邊通過重啟 Redis 也一樣能獲取到剛剛儲存的資料,說明持久化是有生效的~

我們看到上面的 AOF 記錄檔案是不是覺得很規整?但是線上上環境中越規整反而不好,因為這檔案主要是給機器看的,而不是跟我們看的,因此我們最好能夠進行壓縮。

為了解決AOF檔案體積不斷增大的問題,使用者可以向Redis傳送 bgrewriteaof命令,這個命令會通過 通過移除AOF檔案中的冗餘命令 來重寫(rewrite)AOF檔案,使AOF檔案的體積變得儘可能地小。bgrewriteaof的工作原理和 bgsave 建立快照的工作原理非常相似:Redis會建立一個子程式,然後由子程式負責對AOF檔案進行重寫。因為AOF檔案重寫也需要用到子程式,所以快照持久化因為建立子程式而導致的效能問題和記憶體佔用問題,在AOF持久化中也同樣存在。

既然存在手動觸發壓縮,那也存在自動觸發壓縮,這就得說到配置檔案中的兩個配置項

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

該配置項的意思為當AOF檔案的體積大於64MB,並且AOF檔案的體積比上一次重寫之後的體積大了至少一倍(100%)的時候,Redis將執行bgrewriteaof命令。

總結下,它的優點如下:

  • 資料安全。AOF 持久化可以配置 appendfsync 屬性中的 always,每進行一次寫命令操作就會記錄到 AOF 檔案中一次
  • 一致性。通過 append 模型寫檔案,即使中途伺服器當機,也可以通過 redis-check-aof 工具來解決資料一致性問題

缺點如下:

  • AOF 檔案比 RDB 檔案大,而且恢復速度慢
  • 資料集大的時候比 RDB 檔案啟動效率低

同樣是優劣均沾,斟酌使用

三、兩者區別

分別介紹了兩者,我們回顧一下兩者有什麼區別?

方面RDBAOF
持久化方式定時對整個記憶體做快照記錄每一次執行的命令
資料完整性不完整,兩次備份之間會丟失相對完整。取決於刷盤策略
檔案大小會有壓縮,檔案體積小記錄命令,檔案體積很大
當機恢復速度很快
資料恢復優先順序低,因為資料完整性不如AOF高,因為資料完整性更高
系統資源佔用高,大量CPU和記憶體消耗低,主要是磁碟IO資源。且 AOF 重寫時會佔用大量CPU和記憶體資源
使用場景可以容忍數分鐘的資料丟失,追求更快的啟動速度對資料安全性要求較高

看完上面後,想必對兩種持久化機制都有一定的瞭解了。兩者都有優劣勢,那我們該如何選擇?這裡給出幾點意見~

  1. 如果可以忍受一小段時間內的資料丟失,可以使用 RDB 機制,定時生成 RDB 快照, 並且 RDB 恢復資料集的速度也要比 AOF 恢復的速度要快
  2. 但是如果單單使用 RDB 機制,可能導致丟失很多資料,因此我們需要綜合使用 AOFRDB 兩種持久化機制,用 AOF 來保證資料不丟失,作為資料恢復的第一選擇;用 RDB 來做不同程度的冷備份,在 AOF 檔案都丟失或損壞不可用的情況下,可以使用 RDB 來進行快速的資料恢復
  3. 我們可以利用 RDB 來快速恢復資料,並用 AOF 來補全資料

我們到這裡就講述了 Redis 持久化機制的配置,通過這篇文章的學習,我相信到時候面試的時候遇到這個問題也不至於那麼手足無措~!

不要空談,不要貪懶,和小菜一起做個吹著牛X做架構的程式猿吧~點個關注做個伴,讓小菜不再孤單。我們們下文見!

看完不讚,都是壞蛋

今天的你多努力一點,明天的你就能少說一句求人的話!
我是小菜,一個和你一起變強的男人。 ?
微信公眾號已開啟,小菜良記,沒關注的同學們記得關注哦!

相關文章