概述:
Redis是記憶體資料庫,資料都是存儲在記憶體中,為了避免程序退出導緻資料的永久丢失,需要定期将Redis中的資料以某種形式(資料或指令)從記憶體儲存到硬碟;當下次Redis重新開機時,利用持久化檔案實作資料恢複。除此之外,為了進行災難備份,可以将持久化檔案拷貝到一個遠端位置。
Redis持久化分為RDB持久化和AOF持久化:前者将目前資料儲存到硬碟,後者則是将每次執行的寫指令儲存到硬碟 ; 由于AOF持久化的實時性更好,即當程序意外退出時丢失的資料更少,是以AOF是目前主流的持久化方式,不過RDB持久化仍然有其用武之地。
下面依次介紹RDB持久化和AOF持久化:
一. RDB持久化
RDB持久化是将目前程序中的資料生成快照儲存到硬碟(是以也稱作快照持久化),儲存的檔案字尾是rdb;當Redis重新啟動時,可以讀取快照檔案恢複資料。
如果手動删除 dump.rdb 檔案後,重新開機伺服器後資料會全部丢失
1. 觸發條件
1) 手動觸發
save指令和bgsave指令都可以生成RDB檔案。
save指令會阻塞Redis伺服器程序,直到RDB檔案建立完畢為止,在Redis伺服器阻塞期間,伺服器不能處理任何指令請求。

而bgsave指令會建立一個子程序,由子程序來負責建立RDB檔案,父程序(即Redis主程序)則繼續處理請求。
此時 redis 伺服器執行日志如下:
bgsave指令執行過程中,隻有在執行fork操作建立子程序時會阻塞伺服器,而對于save指令,整個過程都會阻塞伺服器,是以save已基本被廢棄,線上環境要杜絕save的使用;此外,在自動觸發RDB持久化時,Redis也會選擇bgsave而不是save來進行持久化;
2) 自動觸發
save m n
自動觸發最常見的情況是在配置檔案中通過save m n,指定當m秒内發生n次變化時,會觸發bgsave。
例如,檢視redis的預設配置檔案(Linux下為redis根目錄下的redis.conf),可以看到如下配置資訊:
其中save 900 1的含義是:當時間到900秒時,如果redis資料發生了至少1次變化,則執行bgsave;save 300 10和save 60 10000同理。當三個save條件滿足任意一個時,都會引起bgsave的調用。
關閉自動觸發 ,就删除上述三個條件,添加一個 save " "
3) 其他自動觸發機制
- 執行shutdown指令時,自動執行rdb持久化
- 在主從複制場景下,如果從節點執行全量複制操作,則主節點會執行bgsave指令,并将rdb檔案發送給從節點
2. RDB檔案
1) 存儲路徑
RDB檔案是經過壓縮的二進制檔案,RDB檔案的存儲路徑既可以在啟動前配置,也可以通過指令動态設定。
通過指令動态設定:dir配置指定目錄,dbfilename指定檔案名。預設是Redis根目錄下的dump.rdb檔案。如下所示(Windows環境):
進入到對應的目錄中可找到該檔案(修改在伺服器重新開機後失效):
啟動前配置:修改配置檔案來修改存儲rdb檔案的位置(修改長期有效):
注 : dir ./:RDB檔案和AOF檔案所在目錄
2) 加載時機
RDB檔案的載入工作是在伺服器啟動時自動執行的,并沒有專門的指令。但是由于AOF的優先級更高,是以當AOF開啟時,Redis會優先載入AOF檔案來恢複資料;隻有當AOF關閉時,才會在Redis伺服器啟動時檢測RDB檔案,并自動載入。伺服器載入RDB檔案期間處于阻塞狀态,直到載入完成為止。
Redis載入RDB檔案時,會對RDB檔案進行校驗,如果檔案損壞,則日志中會列印錯誤,Redis啟動失敗。
3.優缺點
不能完全避免資料丢失 : 因為RDB是每隔一段時間寫入資料,是以系統一旦在定時持久化之前出現當機現象,此前沒有來得及寫入磁盤的資料都将丢失。
檔案相對較小;
執行效率更高.
二. AOF持久化:
RDB持久化是将程序資料寫入檔案,而AOF持久化(即Append Only File持久化),則是将Redis執行的每次寫指令記錄到單獨的日志檔案中;當Redis重新開機時再次執行AOF檔案中的指令來恢複資料。
與RDB相比,AOF的實時性更好,是以已成為主流的持久化方案。
1. 開啟AOF
Redis伺服器預設開啟RDB,關閉AOF;要開啟AOF,需要在配置檔案中配置:appendonly yes
2. 執行流程
由于需要記錄Redis的每條寫指令,是以AOF不需要觸發.
AOF的執行流程包括:
- 指令追加(append):将Redis的寫指令追加到緩沖區aof_buf;
- 檔案寫入(write)和檔案同步(sync):根據不同的同步政策将aof_buf中的内容同步到硬碟;
- 檔案重寫(rewrite):定期重寫AOF檔案,達到壓縮的目的。
1) 指令追加(append)
Redis先将寫指令追加到緩沖區,而不是直接寫入檔案,主要是為了避免每次有寫指令都直接寫入硬碟,導緻硬碟IO成為Redis負載的瓶頸。
2) 檔案寫入(write)和檔案同步(sync)
Redis提供了多種AOF緩存區的同步檔案政策,政策涉及到作業系統的write函數和fsync函數,說明如下:
為了提高檔案寫入效率,在現代作業系統中,當使用者調用write函數将資料寫入檔案時,作業系統通常會将資料暫存到一個記憶體緩沖區裡,當緩沖區被填滿或超過了指定時限後,才真正将緩沖區的資料寫入到硬碟裡。這樣的操作雖然提高了效率,但也帶來了安全問題:如果計算機停機,記憶體緩沖區中的資料會丢失;是以系統同時提供了fsync、fdatasync等同步函數,可以強制作業系統立刻将緩沖區中的資料寫入到硬碟裡,進而確定資料的安全性。
AOF緩存區的同步檔案政策由參數 appendfsync 控制,各個值的含義如下:
- always:指令寫入aof_buf後立即調用系統fsync操作同步到AOF檔案,fsync完成後線程傳回。這種情況下,每次有寫指令都要同步到AOF檔案,硬碟IO成為性能瓶頸,Redis隻能支援大約幾百TPS寫入,嚴重降低了Redis的性能;即便是使用固态硬碟(SSD),每秒大約也隻能處理幾萬個指令,而且會大大降低SSD的壽命。
- no:指令寫入aof_buf後調用系統write操作,不對AOF檔案做fsync同步;同步由作業系統負責,通常同步周期為30秒。這種情況下,檔案同步的時間不可控,且緩沖區中堆積的資料會很多,資料安全性無法保證。
- everysec:指令寫入aof_buf後調用系統write操作,write完成後線程傳回;fsync同步檔案操作由專門的線程每秒調用一次。everysec是前述兩種政策的折中,是性能和資料安全性的平衡,是以是Redis的預設配置,也是我們推薦的配置。
配置檔案如下圖:
3) 檔案重寫(rewrite)
随着時間流逝,Redis伺服器執行的寫指令越來越多,AOF檔案也會越來越大;過大的AOF檔案不僅會影響伺服器的正常運作,也會導緻資料恢複需要的時間過長。
檔案重寫是指定期重寫AOF檔案,減小AOF檔案的體積。需要注意的是,AOF重寫是把Redis程序内的資料轉化為寫指令,同步到新的AOF檔案;不會對舊的AOF檔案進行任何讀取、寫入操作!
關于檔案重寫需要注意的另一點是:對于AOF持久化來說,檔案重寫雖然是強烈推薦的,但并不是必須的;即使沒有檔案重寫,資料也可以被持久化并在Redis啟動的時候導入;是以在一些實作中,會關閉自動的檔案重寫,然後通過定時任務在每天的某一時刻定時執行。
檔案重寫之是以能夠壓縮AOF檔案,原因在于:
- 過期的資料不再寫入檔案
- 無效的指令不再寫入檔案 : 如有些資料被重複設值(set mykey v1, set mykey v2)、有些資料被删除了(sadd myset v1, del myset)等等
- 多條指令可以合并為一個 : 如sadd myset v1, sadd myset v2, sadd myset v3可以合并為sadd myset v1 v2 v3。
檔案重寫的觸發
檔案重寫的觸發,分為手動觸發和自動觸發:
手動觸發:直接調用 bgrewriteaof 指令,該指令的執行與bgsave有些類似:都是fork子程序進行具體的工作,且都隻有在fork時阻塞。預設在redis根目錄下生成 appendonly.aof 檔案
自動觸發:根據auto-aof-rewrite-min-size和auto-aof-rewrite-percentage參數,以及aof_current_size和aof_base_size狀态确定觸發時機。
- auto-aof-rewrite-min-size:執行AOF重寫時,檔案的最小體積,預設值為 67108864 位元組 (64MB)。
- auto-aof-rewrite-percentage:執行AOF重寫時,目前AOF大小(aof_current_size)和上一次重寫時AOF大小(aof_base_size)的比值。