redis緩存架構詳解(二)-redis持久化-RDB持久化詳解

2. redis持久化

接下來,我們講解redis企業級的持久化方案。

2.1. redis持久化的意義

redis持久化的意義,在於故障恢復。

我們部署redis,作爲cache緩存的同時,也可以保存一些較爲重要的數據。如果redis沒有持久化,redis遇到災難性故障的時候,就會丟失所有的數據。

​ 通過持久化將數據備份一份到磁盤,然後定期同步和備份到一些雲存儲服務上去,當redis服務器出現災難時,就可以從雲存儲上拉取數據,恢復到新的redis緩存中,保證數據不丟失全部,能恢復一部分數據。

如下圖,redis持久化的意義:

在這裏插入圖片描述

​ 企業級的redis集羣架構,支撐海量數據、高併發、高可用,而持久化功能提供的災難恢復,數據恢復,爲redis集羣架構的高可用提供有力保障。

​ 當redis整個集羣架構掛了,redis就不可用,我們要讓redis儘快恢復,提供服務。

​ 1、redis沒有做持久化,重啓redis後,也不可用,因爲沒有數據。就會導致大量的請求過來,緩存全部無法命中,就會直接去訪問數據庫,導致緩存雪崩問題。

​ 2、 redis做了持久化,具備緩存的備份和恢復方案,那麼即使redis故障了,也可以通過備份數據,快速恢復,一旦恢復立即對外提供服務。

redis中的數據受內存大小限制,存放數據的量不是無限增長,到一定時間,redis會通過緩存淘汰算法LRU,自動將一部分數據從內存中給清除。     

redis的持久化與系統的高可用是有直接關係。redis持久化主要有RDB,AOF兩種方式。

2.2. RDB持久化

2.2.1. RDB原理

RDB 的全稱是 Redis database. 顧名思義,RDB 就是將 Redis 數據庫,用來存儲數據的,所以通過RDB方式持久化,就是將存在Redis內存中的數據週期性的寫入到 RDB文件中保存到磁盤上,從而實現持久化的。

​ 既然RDB機制是通過把某個時刻的所有數據生成一個快照來保存,那麼就應該有一種觸發機制,是實現這個過程。對於RDB來說,提供了三種機制:save、bgsave、自動化。我們分別來看一下

2.2.2. redis生成RDB文件的觸發機制

(1) save觸發方式

​ 該命令會阻塞當前Redis服務器,執行save命令期間,Redis不能處理其他命令,直到RDB過程完成爲止。具體流程如下:

在這裏插入圖片描述

​ 執行完成時候如果存在老的RDB文件,就把新的替代掉舊的。我們的客戶端可能都是幾萬或者是幾十萬,這種方式顯然不可取。

(2) bgsave觸發方式

​ 執行該命令時,Redis會在後臺異步進行快照操作,快照同時還可以響應客戶端請求。具體流程如下:

在這裏插入圖片描述

​ 具體操作是Redis進程執行fork操作創建子進程,RDB持久化過程由子進程負責,完成後自動結束。阻塞只發生在fork階段,一般時間很短。基本上 Redis 內部所有的RDB操作都是採用 bgsave 命令。

save與bgsave的優缺點:

命令 IO類型 阻塞 複雜度 優點 缺點
save 同步 O(n) 不會消耗額外內存 阻塞客戶端命令
bgsave 異步 是(阻塞發生在fork,時間很短) O(n) 不阻塞客戶端命令 需要fork,消耗內存

(3) 自動觸發

自動觸發是由我們的配置文件來完成的。在redis.conf配置文件中,裏面有如下配置,我們可以去設置:

①save:這裏是用來配置觸發 Redis的 RDB 持久化條件,也就是什麼時候將內存中的數據保存到硬盤。比如“save m n”。表示m秒內數據集存在n次修改時,自動觸發bgsave。

在這裏插入圖片描述

默認如下配置:

save 900 1 #表示900秒內如果有1個key的值變化,則保存

save 300 10 #表示300秒內如果有10個key的值變化,則保存

save 60 10000 #表示60秒內如果有10000個key的值變化,則保存

不需要持久化,那麼你可以註釋掉所有的 save 行來停用保存功能。


2.2.3.RDB持久化機制的優點

(1)非常適合做冷備份
RDB會生成多個數據文件,每個數據文件都代表了某一個時刻中redis的數據,這種多個數據文件的方式,非常適合做冷備,可以將這種完整的數據文件發送到一些遠程的雲存儲上去,如阿里雲、亞馬遜等,以預定好的備份策略來定期備份redis中的數據。

(2)redis 性能高
使用RDB,使redis對外提供的讀寫服務影響非常小,可以讓redis保持高性能,因爲redis主進程只需要fork一個子進程,讓子進程執行磁盤IO操作來進行RDB持久化即可。

(3)重啓和恢復redis進程,更加快速

​ 相對於AOF持久化機制來說,直接基於RDB數據文件來重啓和恢復redis進程,更加快速。


2.2.4. RDB持久化機制的缺點

(1)丟失數據比AOF嚴重

​ 如果想要在redis故障時,儘可能少的丟失數據,那麼RDB沒有AOF好。一般來說,RDB數據快照文件,都是每隔5分鐘,或者更長時間生成一次,如果redis進程宕機,那麼會丟失最近5分鐘的數據。

(2)生成RDB文件特別大時,容易導致服務暫停

​ RDB每次在fork子進程來執行RDB快照數據文件生成的時候,如果數據文件特別大,可能會導致對客戶端提供的服務暫停數毫秒,或者甚至數秒。


2.2.5. RDB持久化配置及數據恢復實驗

1、如何配置RDB持久化機制

redis.conf文件,也就是/etc/redis/6379.conf,去配置持久化

save 60 1000

每隔60s,如果有超過1000個key發生了變更,那麼就生成一個新的dump.rdb文件,就是當前redis內存中完整的數據快照,這個操作也被稱之爲snapshotting(快照)。

也可以手動調用save或者bgsave命令,同步或異步執行rdb快照生成

save可以設置多個,就是多個snapshotting檢查點,每到一個檢查點,就會去check一下,是否有指定的key數量發生了變更,如果有,就生成一個新的dump.rdb文件


2、RDB持久化機制的工作流程

(1)redis根據配置自己嘗試去生成rdb快照文件
(2)fork一個子進程出來
(3)子進程嘗試將數據dump到臨時的rdb快照文件中
(4)完成rdb快照文件的生成之後,就替換之前的舊的快照文件

dump.rdb,每次生成一個新的快照,都會覆蓋之前的老快照


3、基於RDB持久化機制的數據恢復實驗

(1)在redis中保存幾條數據,立即停掉redis進程,然後重啓redis,看看剛纔插入的數據還在不在

數據還在,爲什麼?

帶出來一個知識點,通過redis-cli SHUTDOWN這種方式去停掉redis,其實是一種安全退出的模式,redis在退出的時候會將內存中的數據立即生成一份完整的rdb快照

/var/redis/6379/dump.rdb

(2)在redis中再保存幾條新的數據,用kill -9粗暴殺死redis進程,模擬redis故障異常退出,導致內存數據丟失的場景

這次就發現,redis進程異常被殺掉,數據沒有進dump文件,幾條最新的數據就丟失了

(3)手動設置一個save檢查點,save 5 1
(4)寫入幾條數據,等待5秒鐘,會發現自動進行了一次dump rdb快照,在dump.rdb中發現了數據
(5)異常停掉redis進程,再重新啓動redis,看剛纔插入的數據還在

2.3. AOF持久化

​ AOF機制對每條寫入命令以append-only的模式寫入一個日誌文件中,在redis重啓的時候,可以通過回放AOF日誌中的寫入指令來重新構建整個數據集。

2.3.1. AOF持久化原理

AOF持久化原理如下:

在這裏插入圖片描述

每當有一個寫命令過來時,就直接保存在我們的AOF文件中。

AOF 持久化功能的實現可以分爲命令追加( append )、文件寫入( write )、文件同步( sync )、文件重寫(rewrite)和重啓加載(load)。其流程如下:
  • 所有的寫命令會追加到 AOF 緩衝中。
  • AOF 緩衝區根據對應的策略向硬盤進行同步操作。
  • 隨着 AOF 文件越來越大,需要定期對 AOF 文件進行重寫,達到壓縮的目的。
  • 當 Redis 重啓時,可以加載 AOF 文件進行數據恢復。

2.3.2.文件重寫原理

AOF的方式也同時帶來了另一個問題。持久化文件會變的越來越大。爲了壓縮aof的持久化文件,redis提供了bgrewriteaof命令,將內存中的數據以命令的方式保存到臨時文件中,同時會fork出一條新進程來將文件重寫。

在這裏插入圖片描述

重寫aof文件的操作,並沒有讀取舊的aof文件,而是將整個內存中的數據庫內容用命令的方式重寫了一個新的aof文件,這點和快照有點類似。

2.3.3.AOF也有三種觸發機制

(1)每修改就同步always:同步持久化 每次發生數據變更會被立即記錄到磁盤,性能較差,但數據完整性比較好。

(2)每秒同步everysec:異步操作,每秒記錄,如果一秒內宕機,有數據丟失。

(3)不同no:從不同步。

always、everysec、no之間的優缺點:

命令 優點 缺點
always 不丟失數據 IO開銷大,一般的sata盤只有幾百TPS
everysec 每秒一次fsync 丟1秒數據
no 不用管 不可控

2.3.4. AOF持久化機制的優點

(1)AOF可以更好的保護數據不丟失

AOF可以更好的保護數據不丟失,一般AOF會每隔1秒,通過一個後臺線程執行一次fsync操作,最多丟失1秒鐘的數據

(2)寫入性能非常高,文件不容易破損

AOF日誌文件以append-only模式寫入,所以沒有任何磁盤尋址的開銷,寫入性能非常高,而且文件不容易破損,即使文件尾部破損,也很容易修復

(3)AOF日誌文件過大,也不會影響客戶端的讀寫

AOF日誌文件即使過大的時候,出現後臺重寫操作,也不會影響客戶端的讀寫。因爲在rewrite log的時候,會對其中的指導進行壓縮,創建出一份需要恢復數據的最小日誌出來。再創建新日誌文件的時候,老的日誌文件還是照常寫入。當新的merge後的日誌文件ready的時候,再交換新老日誌文件即可。

(4)AOF日誌文件可讀性好,易做災難性恢復

AOF日誌文件的命令通過非常可讀的方式進行記錄,這個特性非常適合做災難性的誤刪除的緊急恢復。比如某人不小心用flushall命令清空了所有數據,只要這個時候後臺rewrite還沒有發生,那麼就可以立即拷貝AOF文件,將最後一條flushall命令給刪了,然後再將該AOF文件放回去,就可以通過恢復機制,自動恢復所有數據


2.3.5. AOF持久化機制的缺點

(1)AOF日誌文件比RDB大

對於同一份數據來說,AOF日誌文件通常比RDB數據快照文件更大

(2)AOF文件同步頻率高,寫入性能相對低

AOF開啓後,支持的寫QPS會比RDB支持的寫QPS低,因爲AOF一般會配置成每秒fsync一次日誌文件,當然,每秒一次fsync,性能也還是很高的。

(3)AOF基於日誌做數據恢復,可能出現與原始數據不一樣的錯誤

以前AOF發生過bug,就是通過AOF記錄的日誌,進行數據恢復的時候,沒有恢復一模一樣的數據出來。所以說,類似AOF這種較爲複雜的基於命令日誌/merge/回放的方式,比基於RDB每次持久化一份完整的數據快照文件的方式,更加脆弱一些,容易有bug。不過AOF就是爲了避免rewrite過程導致的bug,因此每次rewrite並不是基於舊的指令日誌進行merge的,而是基於當時內存中的數據進行指令的重新構建,這樣健壯性會好很多。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章