RDB持久化
RDB文件的生成和載入
生成RDB文件的命令:SAVE和BGSAVE
SAVE命令阻塞Redis進程,BGSAVE使用子線程來進行持久化
RDB文件的載入是服務器在啟動過程中檢測到RDB,自動載入的,此處有個前提:AOF持久化功能處于關閉狀態(tài),否則優(yōu)先使用AOF文件來還原數(shù)據(jù)
自動間歇性保存
//服務器在900秒之內(nèi),對數(shù)據(jù)庫至少進行了一次修改
save 900 1
//服務器在300秒之內(nèi),對數(shù)據(jù)庫至少進行了10次修改
save 300 10
//服務器在60秒之內(nèi),對數(shù)據(jù)庫進行了至少10000次修改
save 60 10000
AOF持久化
AOF持久化是通過保存Redis服務器所執(zhí)行的寫命令來記錄數(shù)據(jù)庫的狀態(tài)的。
持久化過程:
命令追加-->文件寫入-->文件同步
- 命令追加,服務器執(zhí)行一個寫命令之后,會以協(xié)議格式追加到aof_buf緩沖區(qū)的末尾;
- 文件寫入,將命令寫入aof文件,但是未將文件刷入磁盤;
- 文件同步,即刷盤
Redis通過appendfasync參數(shù)來控制持久化行為:
- always,將aof_buf緩沖區(qū)中所有內(nèi)容寫入并同步到AOF文件,該方式下Redis性能最差,但是安全性最高,數(shù)據(jù)丟失控制在一個文件事件之內(nèi);
- everysec,將aof_buf緩沖區(qū)所有內(nèi)容寫入aof文件,每一秒進行一次aof文件同步,該方式Redis在性能和安全性方面做了折中選擇;
- no,將aof——buf緩沖區(qū)所有內(nèi)容寫入aof文件,同步的時間交給操作系統(tǒng)自己決定,該方式Redis性能最好,但是異常宕機可能丟失大量數(shù)據(jù)。
AOF文件記錄服務器的寫命令,隨著服務器在線時間的推移,AOF文件中內(nèi)容會越來越多,甚至可能撐爆磁盤,所以我們需要進行AOF重寫,新的AOF文件和舊的AOF文件保存著相同的Redis狀態(tài),但是不存在數(shù)據(jù)冗余,并且新AOF文件的生成不涉及到對舊AOF文件的讀寫。
Redis是如何進行無阻塞的AOF文件重寫?
當后臺調(diào)用BGREWRITEAOF指令時,Redis會進行無阻塞的進行AOF文件的重寫,Redis會開啟一個子進程,使用子進程可以使父進程,即服務器進程能夠繼續(xù)對外提供服務,同時避免使用鎖的情況下,保證數(shù)據(jù)的安全性。但是存在一個問題,在AOF重寫期間,服務器進程繼續(xù)處理命令請求,新的命令可能對數(shù)據(jù)庫的狀態(tài)進行了修改,使得服務器當前狀態(tài)和重寫后的服務器狀態(tài)不一致,為了解決這個問題,Redis設置了一個AOF重寫緩沖區(qū),當Redis執(zhí)行寫命令時,會同時將命令追加到AOF緩沖區(qū)和AOF重寫緩沖區(qū),那么子進程在執(zhí)行AOF重寫期間服務器需要執(zhí)行三個工作:
- 執(zhí)行客戶端發(fā)送的命令;
- 將執(zhí)行的寫命令追加到AOF緩沖區(qū);
- 將執(zhí)行的命令追加到AOF重寫緩沖區(qū);
當子進程完成重寫之后,會向父進程發(fā)送一個信號,父進程調(diào)用信號處理函數(shù),執(zhí)行以下操作:
- 將AOF重寫緩沖區(qū)中的所有內(nèi)容寫入到新的AOF文件中,這是新的AOF文件狀態(tài)與當前服務器狀態(tài)一致;
- 對新的AOF文件進行改名,原子性的覆蓋現(xiàn)有的AOF文件,完成新舊AOF文件的替換。
注:信號處理函數(shù)處理過程中需要阻塞Redis。