Redis持久化必知必會

Redis是出了名的速度快,那是因爲在內存中進行數據存儲和操作;如果僅僅是在內存中進行數據存儲,那就會導致以下問題:

•數據隨進程退出而消失:當服務器斷電或Redis Server進程退出時,內存肯定隨之釋放,最後數據也會丟失;可能有些小夥伴認爲只是作爲緩存,數據沒有了,重新從數據庫中讀取放在裏面即可,試想,如果是高併發場景,數據庫豈不是壓力很大;•重要數據無法恢復:數據丟失之後無法進行恢復,對於一些重要的數據,只是存在Redis中,而沒有存在關係型數據庫,如果數據丟失便不可恢復;比如刷禮品排行榜,如果數據丟失,用戶肯定不願意的;

對於Redis持久化在工作中和麪試過程中是一個很重要的技術點,必用必考,接下來詳細說說Redis持久化;

正文

Redis針對數據持久化有兩種方案,如下:

RDB(Redis DataBase):快照形式,即指定時間間隔將Redis內存中的快照數據保存在物理磁盤上,數據保存在*.rdb文件中,以二進制的形式進行存儲,恢復數據直接加載即可;•AOF(Append Only File):日誌形式,即將每條寫命令以append-only模式記錄在*.aof文件中,不能修改文件,只能進行追加;後續恢復數據自動執行日誌文件中的命令即可恢復數據;•混合就是RDB和AOF的結合;以上方式都可以通過配置文件輕鬆搞定,來,咱們先從RDB開始;

fork:後續會頻繁提到,簡單解釋一下,fork的作用是複製一個與當前進程一樣的子進程,該子進程的所有數據都和原進程一致。

RDB持久化

理論放到後面再說,先來看看實際操作,再來做總結;上次對配置文件簡單進行說明,這次就直接找到快照那配置就行啦,先看看默認配置:

 

 

通過 save <seconds> <changes>進行條件配置,如果觸發條件就自動進行RDB持久化操作。默認配置中包含以下三種條件,滿足其中一個就自動保存數據到磁盤:

save 900 1:900秒內(15分鐘)至少有1個key的值進行修改;•save 300 10:300秒內(五分鐘)至少有10個key的值進行修改;•save 60 10000:900秒內(1分鐘)至少有10000個key的值進行修改;

測試驗證

爲了測試時間方便,將其中一個條件改爲1分鐘內有3個key的值修改了就進行持久化到磁盤,如下:

1.先將原有的dump.rdb文件刪除掉,避免影響測試效果;2.修改配置文件如下:

3.用修改之後,指定該配置文件重啓redis-server,然後開始測試;

 

4.嘗試打開dump.rdb看看,咋一看是看不懂,但其實是有對應關係的,這裏就不深究了

 

 

Redis強大吧,不知不覺的就把數據備份,主要是還不影響正常操作,上圖中第四步中就有體現,主進程fork了子進程進行備份,主進程不參與備份持久化操作。既然備份文件有了,如何進行恢復數據呢? redis-server在啓動的時候自動將當前目錄中的備份文件(dump.rdb)數據加載到內存中;如下圖所示:

RDB其他配置項

那爲什麼是dump.rdb文件?,爲什麼又是當前目錄?,如果rdb備份文件寫入失敗了怎麼辦?這些通過配置文件中SNAPSHOTTING部分都有詳細的說明,並提供相關配置項進行設置,如下:

stop-writes-on-bgsave-error:默認設置爲yes,即當RDB備份數據失敗時,Redis會停止接收數據,保證數據的一致性;如果對數據一致性要求不高的,可以將其進行關閉,設置爲no,但推薦都開啓;•rdbcompression:默認設置爲yes,開啓壓縮之後會採用LZF算法對備份文件dump.rdb進行壓縮,但會消耗點CPU性能進行處理,但影響並不大,推薦都開啓;•rdbchecksum:默認設置爲yes,即開啓之後會對備份文件數據進行校驗,但會消耗CPU性能,如果追求性能提高可以將其關閉,但影響也不大,推薦都開啓;•dbfilename:默認爲dump.rdb,即默認的備份文件名爲dump.rdb,可以通過這個配置進行修改;•dir:默認爲當前目錄,即備份的文件存放的目錄。

RDB手動觸發備份

上面說到自動觸發備份,其實在實際應用場景中,有些需求很急,如果要求等到滿足條件備份完成之後才處理問題,間隔時間短還好點,如果間隔時間超過5分鐘,估計等待處理問題的人要上房揭瓦啦;Redis同樣爲大家考慮到了,提供手動備份的方式,如下:

save:直接執行save命令,但會阻塞主進程操作,只能等待備份完成之後才能進行其他處理;•bgsave:直接執行bgsave命令,主進程會fork一個子進程進行備份操作,不阻塞主進程;當數據過大時,可能會在fork的時候有短暫的耗時,但影響不大;上面的自動備份其實最後也是bgsave這種模式。•flushall:執行flushall命令會觸發RBD備份,但是備份文件是空的,在本地測試一把就行了,沒有任何意義,千萬別在生產庫上用

簡單測試一下,刪除dump.rdb文件,將配置文件恢復到默認值,然後指定配置文件重啓redis-server,如下:

如何停止或禁用RDB快照自動備份

可以通過配置文件的形式配置,也可以通過命令的形式進行關閉,但通過命令的方式,服務器重啓之後就失效了,所以一般建議通過配置文件進行配置;

配置文件方式:去除所有關於save的配置,或者配置一個save ""即可,重啓redis-server;•命令方式:在客戶端中執行config set save ""即可,但redis-server重啓時就恢復默認值了;

RDB備份流程

簡要說明:

1.當觸發bgsave持久化時(滿足配置條件或手動執行bgsave命令),主進程fork一個子進程進行持久化操作,主進程不參與任何持久化IO操作;2.爲了不影響原有rdb文件的使用,子進程會將快照數據先寫入到臨時文件;3.當快照數據完全備份到臨時文件時,就替換掉原有的rdb文件,從而得到最新數據的rdb文件;注:當執行sava命令的時候,會導致阻塞,只有等快照數據持久化完成之後,才能做其他事情;

RDB持久化優缺點

每一項技術在解決已有問題的時候,肯定也會帶來新問題,RDB用來解決持久化問題,那它有什麼優缺點呢?

優點

•RDB保存的數據文件比較緊湊,對比AOF來說,相同數據的文件大小比較小;•大量數據持久化時速度相對AOF比較快;•RDB中bgsave模式對主進程影響比較小,只有在主進程fork子進程的時候耗費資源,但影響不大;自動備份後臺用的就是bgsave模式;

缺點

•RDB可能會丟失最後一次沒有備份的數據,如果在最後一次沒開始備份之前,服務器掛了,那最後一次的數據就沒了;•當數據量巨大時,主進程在fork子進程的時候,可能會導致稍微的卡頓;

AOF持久化

既然已經有了RDB持久化了,那爲什麼還得出一個AOF呢?從RDB的缺點來看,很大程度上是因爲可能會丟失最後一次備份之前的數據,對於一些重要數據來說,是不能接受的。而AOF的出現,將數據丟失風險極大的降低。先不說那麼多,實操一把再慢慢聊。

AOF默認情況是沒開啓的,打開配置文件,爲了不讓RDB備份影響,這裏暫時先將RDB備份禁用掉,如下:

1.禁用RDB備份:

1.開啓AOF備份:根據上一篇文章提到的,先找到APPEND ONLY MODE配置塊,將AOF備份開啓appendonly yes

2.配置好了,指定配置文件重啓redis-server,先來看看效果:當一啓動redis-server的時候,appendonly.aof文件就已經生成了;來,咱們接着敲點命令,如下↓↓↓

 

3.嘗試打開appendonly.aof文件看看,和dump.rdp文件有什麼不同;

 

 

appendonly.aof只記錄寫命令,讀命令不記錄,而且記錄方式是以追加的方式,所以速度相對比較快;

 

 

同RDB一樣,在redis-server重啓時,自動加載AOF文件命令依次執行,最終將數據進行恢復

AOF其他配置項

這就是Redis的強大,針對每一個功能都可以通過配置項進行完成,使用非常方便;

appendonly:默認no,不開啓AOF持久化;可以通過設置爲yes開啓;•appendfilename:默認appendonly.aof,代表生成的AOF日誌文件名,可以更改;•appendfsync:默認everysec,設置同步命令到磁盤的策略,即默認每秒通過fsync進行一次命令同步到磁盤;有三種命令同步策略可以選擇,如下:1.always:只要有寫入命令就通過fsync同步到磁盤,數據完整性好,但效率不好;2.everysec:每秒通過fsync進行一次命令同步到磁盤,可能會導致一秒中數據的丟失,因爲可能在命令還沒同步的時候,機器掛掉等操作,但可接受;綜合考慮,推薦使用這種策略;3.no:不同步,由操作系統處理,這種數據不能保證安全;•auto-aof-rewrite-percentage:默認100,搭配auto-aof-rewrite-min-size一起觸發AOF文件重寫策略,即默認噹噹前AOF文件大小是上次重寫的兩倍時才重寫,爲了避免比率達到觸發條件,但文件很小就觸發重寫的情況,所以搭配auto-aof-rewrite-min-size設置AOF文件的最小重寫大小;即當前AOF文件大小達到比率的同時文件大小不低於auto-aof-rewrite-min-size設置的值才觸發重寫;•auto-aof-rewrite-min-size:默認64mb,搭配auto-aof-rewrite-percentage使用;

AOF觸發重寫

當執行的寫命令過多時,就會導致AOF文件過度增大,而對於一些重複性的命令存在AOF文件中是沒有必要的,如下圖所示:

 

上圖中多次對a1這個Key進行多次寫入,最終的值爲10,可見如果AOF文件中只記錄一條最終值的寫命令豈不是最好,從而減少AOF文件的大小;這裏文件大小肯定達不到自動觸發重寫的條件,這裏就手動觸發,然後再看看AOF文件內容,是否進行了優化,如下:

如上圖可見,重寫之後的AOF文件的確是我們自己想要,是不是覺得Redis更加牛X了;觸發重寫有以下兩種方式:

•自動觸發:即當滿足設置的auto-aof-rewrite-percentageauto-aof-rewrite-min-size值會自動觸發重寫;•手動觸發:在客戶端中執行bgrewriteaof命令;

AOF重寫流程

簡要說明:

1.當觸發到重寫AOF文件時,主進程fork一個子進程,子進程根據內存中的現有數據進行命令精簡化,重寫到新的AOF文件中;2.在子進程正在重寫AOF文件時,如果有新的寫命令,將其存放到重寫緩衝區,同時也同步到原來的AOF文件;3.當子進程重寫完成之後,通知主進程將重寫緩衝區中的新命令寫入到新AOF文件中,完成之後,用新的AOF文件將原來的AOF文件替換;4.最後得到優化之後的AOF文件,減少文件大小;

AOF文件修復

對於AOF文件內容的合法性怎麼解決呢,有可能由於突然事件,比如宕機,導致AOF文件寫入不完整;也有可能有人惡意添加不規範數據,redis會怎麼處理呢?這裏就模擬手動修改AOF文件,如下:

根據提示,使用redis-check-aof --fix <filename>進行修復,如下:

啓動圖就不截了,小夥伴們試試去;還有redis也能對rdb文件修復,文中沒有體現,但小夥伴記得去嘗試一下,用redis-check-rdb這個工具即可,在windows版本中redis沒有提供此工具,去linux用高點的版本實操一把。

AOF持久化優缺點

AOF的出現,是解決了RDB丟失最後一次沒保存的數據,極大的降低了數據丟失的風險,但其也帶來相關問題;

優點

•降低數據丟失風險,如果丟失,最多一秒數據;•以追加方式記錄日誌,速度快;•自動優化AOF文件,文件過大時進行重寫,精簡AOF文件;

缺點

•相同大數據,AOF文件比RDB文件大,佔用磁盤空間;•對於大數據的恢復,速度沒有RDB快;

混合持久化

在redis4.0之後,提供了混合持久化配置開啓功能;混合持久化就是結合RDB和AOF各自優點進行整合的持久化方案,從而解決使用AOF恢復數據較慢的問題;

原理就是在AOF文件的前半段加入RDB快照數據,後面纔是增量數據的命令記錄;在配置文件中進行配置即可:aof-use-rdb-preamble yes,高版本redis都默認開啓這種混合持久化模式;

優點:解決了單純AOF恢復數據較慢的問題;

缺點:不能兼容低版本redis場景;

選擇哪個持久化比較合適?

如果需求對數據完整性要求不是很高,可以接受短時間數據丟失,RDB快照持久化方式是最好不過的選擇;

如果對數據完整性要求比較嚴格,使用AOF日誌形式進行持久化比較合適;

如果redis版本在4.0以上,可以使用混合持久化的方式,降低純AOF文件的恢復數據的時間;

如果僅僅是緩存,緩存數據也不重要,併發也不是很高,可以不用開啓持久化;

注:如果不是使用混合持久化,而是將RDB和AOF同時開啓,redis-server恢復數據的時候會優先使用AOF文件進行數據恢復,因爲AOF文件相對比較完整;

 

from:https://mp.weixin.qq.com/s/MvW3ATlas2KrK4JAAlwhSg

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