使用快照和AOF将Redis資料持久化到硬碟中
轉自https://blog.csdn.net/xlgen157387/article/details/61925524
前言
我們知道Redis是一款記憶體伺服器,就算我們對自己的伺服器足夠的信任,不會出現任何軟體或者硬體的故障,但也會有可能出現突然斷電等情況,造成Redis伺服器中的資料失效。是以,我們需要向傳統的關系型資料庫一樣對資料進行備份,将Redis在記憶體中的資料持久化到硬碟等非易失性媒體中,來保證資料的可靠性。
将Redis記憶體伺服器中的資料持久化到硬碟等媒體中的一個好處就是,使得我們的伺服器在重新開機之後還可以重用以前的資料,或者是為了防止系統出現故障而将資料備份到一個遠端的位置。
還有一些場景,例如:
對于一些需要進行大量計算而得到的資料,放置在Redis伺服器,我們就有必要對其進行資料的持久化,如果需要對資料進行恢複的時候,我們就不需進行重新的計算,隻需要簡單的将這台機器上的資料複制到另一台需要恢複的Redis伺服器就可以了。
- 1
Redis給我們提供了兩種不同方式的持久化方法:快照(Snapshotting) 和 隻追加檔案(append-only-file)。
(1)名詞簡介
快照(RDB):就是我們俗稱的備份,他可以在定期内對資料進行備份,将Redis伺服器中的資料持久化到硬碟中;
隻追加檔案(AOF):他會在執行寫指令的時候,将執行的寫指令複制到硬碟裡面,後期恢複的時候,隻需要重新執行一下這個寫指令就可以了。類似于我們的MySQL資料庫在進行主從複制的時候,使用的是
binlog
二進制檔案,同樣的是執行一遍寫指令;
(2)快照持久化通用的配置:
save 60 1000 #60秒時間内有1000次寫入操作的時候執行快照的建立
stop-writes-on-bgsave-error no #建立快照失敗的時候是否仍然繼續執行寫指令
rdbcompression yes #是否對快照檔案進行壓縮
dbfilename dump.rdb #如何命名硬碟上的快照檔案
dir ./ #快照所儲存的位置
- 2
- 3
- 4
- 5
(3)AOP持久化配置:
appendonly no #是否使用AOF持久化
appendfsync everysec #多久執行一次将寫入内容同步到硬碟上
no-appendfsync-on-rewrite no #對AOF進行壓縮的時候能否執行同步操作
auto-aof-rewrite-percentage 100 #多久執行一次AOF壓縮
auto-aof-rewrite-min-size 64mb #多久執行一次AOF壓縮
dir ./ #AOF所儲存的位置
- 6
需要注意的是:這兩種持久化的方式既可以單獨的使用,也可以同時使用,具體選擇哪種方式需要根據具體的情況進行選擇。
快照持久化
快照就是我們所說的備份。使用者可以将Redis記憶體中的資料在某一個時間點進行備份,在建立快照之後,使用者可以對快照進行備份。通常情況下,為了防止單台伺服器出現故障造成所有資料的丢失,我們還可以将快照複制到其他伺服器,建立具有相同資料的資料副本,這樣的話,資料恢複的時候或者伺服器重新開機的時候就可以使用這些快照資訊進行資料的恢複,也可以防止單台伺服器出現故障的時候造成資料的丢失。
但是,沒我們還需要注意的是,建立快照的方式,并不能完全保證我們的資料不丢失,這個大家可以很好的了解,因為快照的建立時定時的,并不是每一次更新操作都會建立一個快照的。系統發生崩潰的時候,使用者将丢失最近一次生成快照之後更改的所有資料。是以,快照持久化的方式隻适合于資料不經常修改或者丢失部分資料影響不大的場景。
一、建立快照的方式:
(1)用戶端通過向Redis發送
BGSAVE
指令來建立快照。
使用BGSAVE的時候,Redis會調用fork來建立一個子程序,然後子程序負責将快照寫到硬碟中,而父程序則繼續處理指令請求。
使用場景:
如果使用者使用了save設定,例如:
save 60 1000
,那麼從Redis最近一次建立快照之後開始計算,當“60秒之内有1000次寫入操作”這個條件滿足的時候,Redis就會自動觸發BGSAVE指令。
如果使用者使用了多個save設定,那麼當任意一個save配置滿足條件的時候,Redis都會觸發一次BGSAVE指令。
(2)用戶端通過向Redis發送
SAVE
接收到SAVE指令的Redis伺服器在快照建立完畢之前将不再響應任何其他指令的請求。SAVE指令并不常用,我們通常隻在沒有足夠的記憶體去執行BGSAVE指令的時候才會使用SAVE指令,或者即使等待持久化操作執行完畢也無所謂的情況下,才會使用這個指令;
當Redis通過SHUTDOWN指令接收到關閉伺服器的請求時,或者接收到标準的TERM信号時,會執行一次SAVE指令,阻塞所有的用戶端,不再執行用戶端發送的任何指令,并且在執行完SAVE指令之後關閉伺服器。
二、使用快照持久化注意事項:
我們在使用快照的方式來儲存資料的時候,如果Redis伺服器中的資料量比較小的話,例如隻有幾個GB的時候。Redis會建立子程序并将資料儲存到硬碟裡邊,生成快照所需的時間比讀取資料所需要的時間還要短。
但是,随着資料的增大,Redis占用的記憶體越來越大的時候,BGSAVE在建立子程序的時候消耗的時間也會越來越多,如果Redis伺服器所剩下的記憶體不多的時候,這行BGSAVE指令會使得系統長時間地停頓,還有可能導緻伺服器無法使用。
各虛拟機類别,建立子線程所耗時間:
是以,為了防止Redis因為建立子程序的時候出現停頓,我們可以考慮關閉自動儲存,轉而通過手動的方式發送BGSAVE或者SAVE來進行持久化,
手動的方式發送BGSAVE也會出現停頓的現象,但是我們可以控制發送該指令的時間來控制出現停頓的時候不影響具體的業務請求。
另外,值得注意的是,在使用SAVE指令的時候,雖然會一直阻塞Redis直到快照生成完畢,但是其不需要建立子程序,是以不會向BGSAVE一樣,因為建立子程序而導緻Redis停頓。也正因為如此,SAVE建立快照的速度要比BGSAVE建立快照的速度更快一些。
建立快照的時候,我們可以在業務請求,比較少的時候,比如淩晨三、四點,通過手寫腳本的方式,定時執行。
AOF持久化
AOF持久化會将被執行的寫指令寫到AOF檔案的末尾,以此來記錄資料發生的變化。這樣,我們在恢複資料的時候,隻需要從頭到尾的執行一下AOF檔案即可恢複資料。
一、打開AOF持久化選項
我們可以通過使用如下指令打開AOF:
appendonly yes
我們,通過如下指令來配置AOF檔案的同步頻率:
appendfsync everysec/always/no
二、appendfsync同步頻率的差別
appendfsync同步頻率的差別如下圖:
(1)always的方式固然可以對沒一條資料進行很好的儲存,但是這種同步政策需要對硬碟進行大量的寫操作,是以Redis處理指令的速度會受到硬碟性能的限制。
普通的硬碟每秒鐘隻能處理大約200個寫指令,使用固态硬碟SSD每秒可以處理幾萬個寫指令,但是每次隻寫一個指令,這種隻能怪不斷地寫入很少量的資料的做法有可能引發嚴重的寫入放大問題,這種情況下降嚴重影響固态硬碟的使用壽命。
(2)everysec的方式,Redis以每秒一次的頻率大隊AOF檔案進行同步。這樣的話既可以兼顧資料安全也可以兼顧寫入性能。
Redis以每秒同步一次AOF檔案的性能和不使用任何持久化特性時的性能相差無幾,使用每秒更新一次 的方式,可以保證,即使出現故障,丢失的資料也在一秒之内産生的資料。
(3)no的方式,Redis将不對AOF檔案執行任何顯示的同步操作,而是由作業系統來決定應該何時對AOF檔案進行同步。
這個指令一般不會對Redis的性能造成多大的影響,但是當系統出現故障的時候使用這種選項的Redis伺服器丢失不定數量的資料。
另外,當使用者的硬碟處理寫入操作的速度不夠快的話,那麼緩沖區被等待寫入硬碟的資料填滿時,Redis的寫入操作将被阻塞,并導緻Redis處理指令請求的速度變慢,因為這個原因,一般不推薦使用這個選項。
三、重寫/壓縮AOF檔案
随着資料量的增大,AOF的檔案可能會很大,這樣在每次進行資料恢複的時候就會進行很長的時間,為了解決日益增大的AOF檔案,使用者可以向Redis發送
BGREWRITEAOF
指令,這個指令會通過移除AOF檔案中的備援指令來重寫AOF檔案,是AOF檔案的體檢變得盡可能的小。
BGREWRITEAOF的工作原理和BGSAVE的原理很像:Redis會建立一個子程序,然後由子程序負責對AOF檔案的重寫操作。
因為AOF檔案重寫的時候彙建立子程序,是以快照持久化因為建立子程序而導緻的性能和記憶體占用問題同樣會出現在AOF檔案重寫的 時候。
四、觸發重寫/壓縮AOF檔案條件設定
AOF通過設定
auto-aof-rewrite-percentage
和
auto-aof-rewrite-min-size
選項來自動執行BGREWRITEAOF。
其具體含義,通過執行個體可以看出,如下配置:
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
表示目前AOF的檔案體積大于64MB,并且AOF檔案的體積比上一次重寫之後的體積變大了至少一倍(100%)的時候,Redis将執行重寫BGREWRITEAOF指令。
如果AOF重寫執行的過于頻繁的話,可以将
auto-aof-rewrite-percentage
選項的值設定為100以上,這種最偶發就可以讓Redis在AOF檔案的體積變得更大之後才執行重寫操作,不過,這也使得在進行資料恢複的時候執行的時間變得更加長一些。
驗證快照檔案和AOF檔案
無論使用哪種方式進行持久化,我們在進行恢複資料的時候,Redis提供了兩個指令行程式:
redis-check-aof
redis-check-dump
他們可以再系統發生故障的時候,檢查快照和AOF檔案的狀态,并對有需要的情況對檔案進行修複。
如果使用者在運作redis-check-aof指令的時候,指定了
--fix
參數,那麼程式将對AOF檔案進行修複。
程式修複AOF檔案的方法很簡單:他會掃描給定的AOF檔案,尋找不正确或者不完整的指令,當發現第一個出現錯誤指令的時候,程式會删除出錯指令以及出錯指令之後的所有指令,隻保留那些位于出錯指令之前的正确指令。大部分情況,被删除的都是AOF檔案末尾的不完整的寫指令。
總結
上述,一起學習了兩種支援持久化的方式,一方面我們需要通過快照或者AOF的方式對資料進行持久化,另一方面,我們還需要将持久化所得到的檔案進行備份,備份到不同的伺服器上,這樣才可以盡可能的減少資料丢失的損失。
微信公衆号【黃小斜】大廠程式員,網際網路行業新知,終身學習踐行者。關注後回複「Java」、「Python」、「C++」、「大資料」、「機器學習」、「算法」、「AI」、「Android」、「前端」、「iOS」、「考研」、「BAT」、「校招」、「筆試」、「面試」、「面經」、「計算機基礎」、「LeetCode」 等關鍵字可以擷取對應的免費學習資料。