首先我們要知道什么是持久化:持久化是指將數據保存到磁盤上,以確保在Redis服務器重啟時數據不會丟失。
Redis支持兩種主要的持久化方式:RDB持久化和AOF持久化
下面讓我依次給你介紹一下:
RDB持久化
作用
這是將Redis數據保存到磁盤的一種方式,RDB持久化通過在指定時間間隔內將數據集快照寫入磁盤中。這樣一來即使故障宕機,快照文件也不會丟失,數據的可靠性也就得到了保證.
這個快照文件就稱為RDB文件(dump.rdb),其中,RDB就是Redis DataBase的縮寫。
案例演示
自動觸發
在我們Redis7中
我們可以看到執行的RDB條件
在1600秒內,如果有至少1個鍵被修改,則執行快照?
在300秒內,如果有至少10個鍵被修改,則執行快照
在60秒內,如果有至少10000個鍵被修改,則執行快照
這個條件對于我們演示案例過于苛刻,所以我們修改成5秒2次修改
修改文件保存路徑
現在我們在5秒內修改兩個數據:
當我們超過5秒添加兩個數據:
恢復文件
備份成功后故意用flushdb清空redis,看看是否可以恢復數據
結論:執行flushall/flushdb命令也會產生dump.rdb文件,但里面是空的,無意義
手動觸發
為什么需要手動觸發呢?因為實際生產中需要某個時刻添加一個在重要數據,需要立刻保存就需要手動觸發了。
Redis提供了兩個命令來生成RDB文件,分別是save和bgsave
我們可以看一下官方文檔:
Save:在主程序中執行會阻塞當前redis服務器,直到持久化工作完成執行save命令今期間,Redis不能處理其他命令,線上禁止使用
bgsave
Redis會在后臺異步進行快照操作,不阻塞快照同時還可以響應客戶端請求,該觸發方式會fork一個子進程由子進程復制持久化過程
官方說明:
Redis會使用bgsave對當前內存中的所有數據做快照這個操作是子進程在后臺完成的,這就允許主進程同時可以修改數據
其fork就是在Linux程序中,fork()會產生一個和父進程完全相同的子進程,但子進程在此后多會exec系統調用,出于效率考慮,盡量避免膨脹。
我們可以通過lastsave獲取最后一次成功獲取快照的時間
RDB優點
官網說明:
總結:
- 適合大規模的數據恢復
- 按照業務定時備份
- 對數據完整性和一致性要求不高
- RDB文件在內存中的加載速度要比AOF快很多
RDB缺點
官網說明:
總結:
- 在一定間隔時間做一次備份,所以如果redis意外down掉的話,就會丟失從當前至最近一次快照期間的數據,快照之間的數據會丟失
- 內存數據的全量同步,如果數據量太大會導致I/0嚴重影響服務器性能
- RDB依賴于主進程的fork,在更大的數據集中,這可能會導致服務請求的瞬間延遲。fork的時候內存中的數據被克隆了一份,大致2倍的膨脹性,需要考慮
檢查修復durp.rdb文件
哪些情況會觸發RDB拍照
- 配置文件中的默認的拍照配置
- 手動save/bgsave
- 執行flushall/flushdb命令也會產生dump.rdb文件,但里面是空的,無意義
- 執行shutdown且沒有設置開啟AOF持久化
- 主從復制時,主節點自動觸發
如何禁用快照
動態所有停止RDB保存規則的方法: redis-cli config set save
修改配置:
AOF持久化
官網介紹:
說明:
以日志的形式來記錄每一個寫的操作,將Redis執行過的所有寫指令記錄下來(讀操作不記錄),只許追加文件但不可以改寫文件,redis啟動之初會讀取該文件重新構建數據,換言之,redis重啟的話就根據日志文件的內容將寫指令從前到后執行一次以完成數據的恢復工作
默認情況下,redis是沒有開啟AOF(append only file)的。開啟AOF功能需要設置配置: appendonly yes
工作流程:
1 | Client作為命令的來源,會有多個源頭以及源源不斷的請求命令。 |
2 | 在這些命令到達Redis Server 以后并不是直接寫入AOF文件,會將其這些命令先放入AOF緩存中進行保存。這里的AOF緩沖區實際上是內存中的一片區域,存在的目的是當這些命令達到一定量以后再寫入磁盤,避免頻繁的磁盤IO操作。 |
3 | AOF緩沖會根據AOF緩沖區 同步文件的三種寫回策略將命令寫入磁盤上的AOF文件。 |
4 | 隨著寫入AOF內容的增加為避免文件膨脹,會根據規則進行命令的合并(又稱 AOF重寫),從而起到AOF文件壓縮的目的。 |
5 | 當Redis Server 服務器重啟的時候會從AOF文件載入數據。 |
三種寫回策略:
- Always:同步寫回,每一個命令執行完立刻同步的將日志寫回磁盤
- everysec:每秒寫回,每個寫命令執行完,只是先把日志寫到AOF文件的內存緩沖區,每隔1秒把緩沖區中的內容寫入磁盤
- no:操作系統控制的寫回,每個寫命令執行完,只是先把日志寫到AOF文件的內存緩沖區,由操作系統決定何時將緩沖區內容寫回磁盤
案例演示
開啟AOF
AOF文件保存路徑
在redis7之前:AOF保存文件的位置和RDB保存文件的位置一樣都是通過redis.conf配置文件的 dir 配置
在redis7之后:AOF文件保存路徑變成了dir(rdb保存路徑)+appenddirname
AOF文件保存名稱
在redis7之前:
在redis7之后:
官方說明:
在Redis7之后將一個AOF文件差分為三個文件:base基本文件、incr增量文件、manifest清單文件
文件恢復
正常恢復
寫操作繼續,生成的AOF文件到指定的目錄
恢復:重啟redis然后重新加載
? ? ? ? ? ?
?異常恢復? ? ? ? ? ? ? ?
?故意亂寫正常的AOF文件模擬網絡閃斷文件寫error:修改appendonly.aof.1.incr.aof文件
? ? ??
此時我們啟動redis,發現根本啟動不了一點
使用異常修復命令:redis-check-aof --fix
?成功修復:? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?
AOF優缺點? ?
優點:
官方解釋:
概括:更好的保護數據不丟失、性能高、可做緊急恢復
缺點:? ? ? ? ??
官方解釋:
概括:
- 相同數據集的數據而言AOF文件要遠大于RDB文件,恢復速度慢于RDB
- AOF運行效率低于RDB,每秒同步策略效率較好,不同步頻率和RDB相同
AOF重寫機制
???????????????????????????????
一句話:啟動AOF文件的內容壓縮,只保留可以恢復數據的最小指令集。
由于AOF持久化是Redis不斷將寫命令記錄到 AOF 文件中,隨著Redis不斷的進行,AOF 的文件會越來越大,文件越大,占用服務器內存越大以及 AOF 恢復要求時間越長。
為了解決這個問題,Redis新增了重寫機制,當AOF文件的大小超過所設定的峰值時,Redis就會自動啟動AOF文件的內容壓縮,
只保留可以恢復數據的最小指令集或者可以手動使用命令 bgrewriteaof 來重新。
案例演示
需求說明:
啟動AOF文件的內容壓縮,只保留可以恢復數據的最小指令集。
?舉個例子:比如有個key?
一開始你? set k1 v1
然后改成? set k1 v2
最后改成? set k1 v3
如果不重寫,那么這3條語句都在aof文件中,內容占空間不說啟動的時候都要執行一遍,共計3條命令;
但是,我們實際效果只需要set k1 v3這一條,所以,
開啟重寫后,只需要保存set k1 v3就可以了只需要保留最后一次修改值,相當于給AOF文件瘦身減肥,性能更好。
AOF重寫不僅降低了文件的占用空間,同時更小的AOF也可以更快地被Redis加載。
前期準備
開啟AOF
為了演示我們將自動觸發調小:
關閉融合:
自動觸發
對同一個k不斷地賦值:
當我們的內存到了1k的時候,觸發重寫
手動觸發
客戶端向服務器發送bgrewriteaof
重寫原理
1:在重寫開始前,redis會創建一個“重寫子進程”,這個子進程會讀取現有的AOF文件,并將其包含的指令進行分析壓縮并寫入到一個臨時文件中。
2:與此同時,主進程會將新接收到的寫指令一邊累積到內存緩沖區中,一邊繼續寫入到原有的AOF文件中,這樣做是保證原有的AOF文件的可用性,避免在重寫過程中出現意外。
3:當“重寫子進程”完成重寫工作后,它會給父進程發一個信號,父進程收到信號后就會將內存中緩存的寫指令追加到新AOF文件中
4:當追加結束后,redis就會用新AOF文件來代替舊AOF文件,之后再有新的寫指令,就都會追加到新的AOF文件中
5:重寫aof文件的操作,并沒有讀取舊的aof文件,而是將整個內存中的數據庫內容用命令的方式重寫了一個新的aof文件,這點和快照有點類似
AOF優化配置項詳解
RDB-AOF混合持久化
官網說明

數據恢復順序和加載流程
在同時開啟RDB和AOF的時候,重啟只會加載AOF文件,不會加載RDB文件
????????????????????????????????????????????????????????????? ? ? ? ?
對比
RDB持久化方式能夠在指定的時間間隔能對你的數據進行快照存儲
AOF持久化方式記錄每次對服務器寫的操作,當服務器重啟的時候會重新執行這些命令來恢復原始的數據,AOF命令以edis協議追加保存每次寫的操作到文件未尾
同時開啟兩種持久化方式
在這種情況下,當redis重啟的時候會優先載入AOF文件來恢復原始的數據,因為在通常情況下AOF文件保存的數據集要比RDB文件保存的數據集要完整.
RDB的數據不實時,同時使用兩者時服務器重啟也只會找AOF文件。那要不要只使用AOF呢?
作者建議不要,因為RDB更適合用于備份數據庫(AOF在不斷變化不好備份),留著rdb作為一個萬一的手段
推薦開啟混合模式:
開啟之后:
先使用RDB進行快照存儲,然后使用AOF持久化記錄所有的寫操作,當重寫策略滿足或手動觸發重寫的時候,將最新的數據存儲為新的RDB記錄。這樣的話,重啟服務的時候會從RDB和AOF兩部分恢復數據,既保證了數據完整性,又提高了恢復數據的性能。簡單來說:混合持久化方式產生的文件一部分是RDB格式,一部分是AOF格式。----》AOF包括了RDB頭部+AOF混寫
純緩存模式
同時關閉RDB+AOF
禁用RDB:save ""
禁用AOF:appendonly no