前言
我們知道 Redis 時一個記憶體級的資料庫,如果記憶體中的資料如果突然遭遇斷電,將會丟失 Redis 儲存的資料,那麼為了保證資料不丟失,記憶體中的資料要持久化到硬盤裡來,利用永久性儲存介質將資料進行儲存,在特定的時間將儲存的資料進行恢復的工作機制稱為持久化。持久化的作用就是防止資料的意外丟失,確保資料安全性!也就是為什麼我們每寫會兒文件就要儲存一次的原因。
RDB 持久化策略RDB 是資料快照的持久化策略,只儲存資料結果,儲存格式簡單,關注點在資料。依據執行持久化時機分為如下三種策略
save 即時執行策略save 即使生成策略持久化的命令為 save,會阻塞輸入的指令,save 指令比較耗費伺服器效能!
bgsave 後臺執行策略使用指令bgsave會使用延遲執行 save 策略。
條件 save 後臺執行策略限定時間限定條件的 save 持久化:滿足限定時間內 key 的變化數量達到指定數量則進行持久化。命令為:
save second changes
second 代表指定時間,changes 代表 key 的變化數量,如果設定為:
save 100 10
100 秒內有 10 個 key 變化則進行持久化,那麼如果我在 100 秒到期的時候只有 9 個 key 變化,則重置時間,重新從上一次持久化後的 key 的變化數全量統計變化值【實際上也就是 9 個】,也就是剩餘 100 秒只需再等待一個 key 變化就能進行持久化了。
RDB 三種執行策略對比以下是三種執行 RDB 方式的對比:
RDB 策略的優缺點優點
RDB 儲存效率高【能存更多】,RDB 檔案是緊湊的二進位制檔案,儲存效率高,比較適合做冷備,災備,全量複製的場景。RDB 做會生成多個檔案,每個檔案都代表了某一個時刻的 Redis 完整的資料快照,RDB 這種多個數據檔案的方式,非常適合做冷備,因為大量的一個個的檔案,可以每隔一定的時間,複製出來;可以將這種完整的資料檔案傳送到一些遠端的雲服務、分散式儲存上進行安全的儲存,以預定好的備份策略來定期備份 Redis 中的資料;RDB 恢復資料更快【能恢復更快】,直接基於 RDB 資料檔案來重啟和恢復 Redis 程序,更加快速:RDB 就是一份資料檔案,恢復的時候,直接載入到記憶體中即可;RDB 對 Redis 的讀寫無影響,RDB 對 Redis【不影響 Redis】對外提供的讀寫服務,影響非常小,可以讓 Redis 保持高效能**,因為 Redis 主程序只需要 fork 一個子程序,讓子程序執行磁碟 IO 操作來進行 RDB 持久化即可;RDB 每次寫,都是直接寫 Redis 記憶體,只是在一定的時候,才會將資料寫入磁碟中缺點
RDB 無法做到實時持久化【可能會丟資料】,一般來說,RDB 資料快照檔案,都是每隔 5 分鐘,或者更長時間生成一次,這個時候就得接受一旦 Redis 程序宕機,那麼會丟失最近 5 分鐘的資料;這個問題,也是 RDB 最大的缺點,就是不適合做第一優先的恢復方案,如果你依賴 RDB 做第一優先恢復方案,會導致資料丟失的比較多;RDB 在 fork 子程序時消耗記憶體【有一些記憶體損耗】,RDB 每次在 fork 子程序來執行 RDB 快照資料檔案生成的時候,都會犧牲一些記憶體。RDB 基於快照,每次讀寫都是全量資料,資料量大時效能較低RDB 如果設定的 dump 讀寫時間不合適,大資料量下會有 IO 頻繁的風險AOF 持久化策略AOF 是資料快照的持久化策略,儲存操作過程,儲存格式複雜,關注點在資料的操作過程。我們依據 RDB 的缺點就能理解 AOF 的存在價值了,因為沒有哪種策略是完美的,只有合適的:
RDB 無法做到實時持久化【可能會丟資料】,一般來說,RDB 資料快照檔案,都是每隔 5 分鐘,或者更長時間生成一次,這個時候就得接受一旦 Redis 程序宕機,那麼會丟失最近 5 分鐘的資料;這個問題,也是 RDB 最大的缺點,就是不適合做第一優先的恢復方案,如果你依賴 RDB 做第一優先恢復方案,會導致資料丟失的比較多;RDB 在 fork 子程序時消耗記憶體【有一些記憶體損耗】,RDB 每次在 fork 子程序來執行 RDB 快照資料檔案生成的時候,都會犧牲一些記憶體。RDB 基於快照,每次讀寫都是全量資料,資料量大時效能較低RDB 如果設定的 dump 讀寫時間不合適,大資料量下會有 IO 頻繁的風險基於以上問題,我們看下 AOF 的實現。
只記錄部分資料,不記錄全量資料只記錄操作過程,不記錄操作資料對所有操作均記錄,降低丟失資料的可能性。AOF 也有三種策略:
always 寫資料策略Redis 在每個事件迴圈都要將 AOF 緩衝區中的所有內容寫入到 AOF 檔案,並且同步 AOF 檔案,所以 always 的效率是 appendfsync 選項三個值當中最差的一個,但從安全性來說,也是最安全的。當發生故障停機時,AOF 持久化也只會丟失一個事件迴圈中所產生的命令資料。資料零誤差,效能極低,不推薦使用
everysec 寫資料策略Redis 在每個事件迴圈都要將 AOF 緩衝區中的所有內容寫入到 AOF 檔案中,並且每隔一秒就要在子執行緒中對 AOF 檔案進行一次同步。從效率上看,該模式足夠快。當發生故障停機時,只會丟失一秒鐘的命令資料。準確性較高,效能較高,推薦使用
no 寫資料策略Redis 在每一個事件迴圈都要將 AOF 緩衝區中的所有內容寫入到 AOF 檔案。而 AOF 檔案的同步由作業系統控制。這種模式下速度最快,但是同步的時間間隔較長,出現故障時可能會丟失較多資料
AOF 重寫機制並不是所有的 AOF 資料都需要重寫。
程序裡超時的資料不再重寫,例如程序裡已經過期的一些資料就不再重寫了。忽略無效指令,重寫時使用程序中的最終資料直接生成,這樣 AOF 只保留最終資料生成命令。例如連續冗餘的 set。對同一資料的多條指令進行合併,例如 3 次 incr num,可以調整為:set num 3滿足這些條件就會觸發重寫,以降低 AOF 檔案的記憶體佔用。AOF 執行的重寫原理:
我們最常用的是everysec 開啟重寫這種模式,我們詳細看下這種模式:
RDB 與 AOF 對比學習完了兩種持久化機制後,我們來看下兩種持久化機制的對比:
選擇的時候可以依據如下策略,對資料敏感選擇 AOF【實時】,對資料不敏感選擇 RDB【階段】
文章到這裡就結束了!
下節更新資料物件的底層實現方式!
總結
2020馬上就要過去了,小編這裡整理一些 Redis實戰300多頁的集錦文件;整理好的JAVA核心知識點整理200多頁的學習筆記;2020最新總結的Java面試題禮包!還有 微服務、SSM、 Redis、等技術真題資料,關注小編+轉發文章+私信【Redis】獲取上述資料~ 重要的事情說三遍,轉發+轉發+轉發,一定要記得轉發哦!!!