為什麼要持久化
Redis是記憶體資料庫,如果不將記憶體中的資料庫狀態儲存到磁碟中,那麼一旦伺服器程式退出,伺服器的資料庫狀態就會消失(即斷電即失)。為了保證資料不丟失,我們需要將
記憶體中的資料儲存到磁碟,以便 Redis 重啟時能夠從磁碟中恢復原有的資料,而整個過程就叫做 Redis 持久化。
Redis 持久化也是 Redis 和 Memcached 的主要區別之一,因為 Memcached 是不具備持久化功能的。
持久化的幾種方式
Redis 持久化擁有以下三種方式:
快照方式
(RDB, Redis DataBase)將某一個時刻的記憶體資料,以二進位制的方式寫入磁碟;
檔案追加方式
(AOF, Append Only File),記錄所有的寫操作命令,並以文字的形式追加到檔案中;
混合持久化方式
,Redis 4.0 之後新增的方式,混合持久化是結合了 RDB 和 AOF 的優點,在寫入的時候,先把當前的資料以 RDB 的形式寫入檔案的開頭,再將後續的操作命令
以 AOF 的格式存入檔案,這樣既能保證 Redis 重啟時的速度,又能避免資料丟失的風險。
因為每種持久化方案,都有特定的使用場景,讓我們先從 RDB 持久化說起吧。
一、什麼是RDB,RDB如何實現持久化?
1、什麼是RDB?
RDB是Redis Database 的縮寫,其作用是在某一個時間點,將Redis儲存在記憶體中的資料生成快照並儲存到磁碟等介質上,存在這個磁碟介質上的檔案就是RDB檔案。“快照”顧名
思義就是好像照相一樣儲存當時的資料,這裡RDB檔案是一個二進位制的檔案,並且是經過壓縮的。因為RDB檔案是儲存在硬碟中的,即使Redis伺服器程式退出,甚至執行Redis
伺服器的計算機當機,但只要RDB檔案仍然存在,Redis伺服器就可以用它來還原資料庫狀態。
2、觸發方式(手動、自動)
RDB 的持久化觸發方式有兩類:一類是手動觸發,另一類是自動觸發。
1)手動觸發
(執行 save 或者 bgsave 命令)
手動觸發持久化的操作有兩個命令: save 和 bgsave ,它們主要區別體現在:是否阻塞 Redis 主執行緒的執行
。
save命令
redis 127.0.0.1:6379> SAVE
在客戶端中執行 save 命令,就會觸發 Redis 的持久化,但同時也是使 Redis 處於阻塞狀態,直到 RDB 持久化完成,才會響應其他客戶端發來的命令,
所以在生產環境一定要慎用
。
bgsave命令
redis 127.0.0.1:6379> BGSAVE
bgsave(background save)既後臺儲存的意思, 它和 save 命令最大的區別就是 bgsave 會 fork() 一個子程式來執行持久化,整個過程中只有在 fork() 子程式時有短暫的
阻塞,當子程式被建立之後,Redis 的主程式就可以響應其他客戶端的請求了,相對於整個流程都阻塞的 save 命令來說,顯然 bgsave 命令更適合我們使用。
在快照進行的過程中,也就是生成檔案的過程中,不會對原有的RDB檔案進行修改,直到快照生成完畢,直接將老的替換成新的,保證rdb檔案任何時刻都是完整的。
2) 自動觸發
自動觸發的含義就是不用我們手動命令去觸發持久化,而是通過配置當滿足某一規則的時候自動去執行 bgsave 命令。
Redis的配置檔案就預設設定了3個儲存點:
# 以下配置表示的條件:
# 900秒內有1個key發生了變化,則觸發儲存RDB檔案
save 900 1
# 伺服器在300秒之內被修改了10次
save 300 10
# 伺服器在60秒之內被修改了10000次
save 60 10000
#如果想禁用快照儲存的功能,可以通過註釋掉所有"save"配置達到,或者在最後一條"save"配置後新增如下的配置:
save ""
注意這裡滿足條件執行的是bgsave
命令。
二、什麼是AOF,AOF如何實現持久化?
1、什麼是AOF?
以日誌的形式來記錄每個寫操作,將Redis執行過的所有寫指令記錄下來(讀操作不記錄),只許追加檔案但不可以改寫檔案,redis啟動之初會讀取該檔案重新構建資料,
換言之,redis重啟的話就根據日誌檔案的內容將寫指令從前到後執行一次以完成資料的恢復工作 。
預設情況下,redis是沒有開啟AOF(append only file)的。開啟AOF功能需要設定配置:appendonly yes 。
2、AOF持久化流程
上面提到了AOF持久化的過程就是日誌不斷追加的過程,這裡通過圖 給大家介紹具體流程:
1、Client作為命令的來源,會有多個源頭以及源源不斷的請求命令。
2、在這些命令到達Redis Server 以後,並不是直接寫入AOF檔案,會將其這些命令先放入AOF快取中進行儲存。這裡的AOF緩衝區實際上是記憶體中的一片區域,存在的目
的是當這些命令達到一定量以後再寫入磁碟,避免頻繁的磁碟IO操作。
3、AOF緩衝會根據對應的策略
將命令寫入磁碟上的AOF檔案。
4、AOF檔案隨著寫入檔案內容的增加,會根據規則進行命令的合併,這裡叫做AOF重寫
,從而起到AOF檔案壓縮的目的。
5、當Redis Server 伺服器重啟的時候會從AOF檔案載入資料。
這裡面有兩點需要在詳細寫: AOF緩衝區同步檔案策略 和 AOF重寫機制。
3、AOF緩衝區同步檔案策略
上面提到了Redis 會將命令先寫入到AOF緩衝區,再寫入AOF檔案。這裡介紹一下AOF緩衝區同步檔案的三個策略。
#aof持久化策略的配置
appendfsync always #always表示每次寫入都執行fsync,以保證資料同步到磁碟
appendfsync everysec #everysec表示每秒執行一次fsync,可能會導致丟失這1s資料
appendfsync no #no表示不執行fsync,由作業系統保證資料同步到磁碟,速度最快
Always策略 的同步操作是在主程式的主執行緒中進行的,由於fsync的阻塞特性,會導致其掛起,在此期間無法服務新的請求,因而吞吐量下降,但確實能夠保證記憶體和硬碟中
資料的一致性。
Everysec策略 的同步操作是通過後臺I/O執行緒進行的,由於是在子執行緒中進行,所以主執行緒並不會被阻塞,可以繼續服務新的請求,但是記憶體和硬碟中的資料會有1秒的差別
(不一定精準),這是一種折衷的方案,尋求了一個平衡。
No策略 則是將同步操作的控制權交由作業系統,不阻塞主執行緒,但是資料一致性可能會偏差很大
官方建議使用預設配置每秒同步,它既快速又安全。這個always策略在實踐中非常緩慢, 沒有辦法做得fsync比現在更快。
4、AOF重寫機制
(1)是什麼?
AOF採用檔案追加方式,檔案會越來越大為避免出現此種情況,新增了重寫機制,當AOF檔案的大小超過所設定的閾值時,Redis就會啟動AOF檔案的內容壓縮, 只保留可以恢復
資料的最小指令集。
舉個例子:比如有個key 一開始你 set key 1,然後改成 set key 2,最後 set key 3。如果不重寫那麼這3條語句都在檔案中,這樣即佔空間,啟動的時候都要執行一遍無效
的命令,如果重寫後,只需要儲存set key 3 就可以了。
AOF重寫不僅降低了檔案的佔用空間,同時更小的AOF也可以更快地被Redis載入。
(2)觸發機制(手動、自動)
手動:客戶端向伺服器傳送bgrewriteaof命令
自動:滿足配置檔案中的選項後,自動執行bgrewriteaof命令。Redis會記錄上次重寫時的AOF大小,預設配置是當AOF檔案大小是上次rewrite後大小的一倍且檔案大於64M時
觸發。
(3)重寫原理
AOF檔案持續增長而過大時,會fork出一條新程式來將檔案重寫(也是先寫臨時檔案最後再rename),遍歷新程式的記憶體中資料,每條記錄有一條的Set語句。重寫aof檔案的操作,
並沒有讀取舊的aof檔案, 而是將整個記憶體中的資料庫內容用命令的方式重寫了一個新的aof檔案,這點和快照有點類似。
三、RDB和AOF各自優缺點
1、RDB的優點
(1)比起AOF,在資料量比較大的情況下,RDB的啟動速度更快。
(2)RDB檔案是一個很簡潔的單檔案,它儲存了某個時間點的Redis資料,很適合用於做備份。
(3)RDB的效能很好,需要進行持久化時,主程式會fork一個子程式出來,然後把持久化的工作交給子程式,自己不會有相關的I/O操作。
2、RDB缺點
(1)RDB容易造成資料的丟失。假設每5分鐘儲存一次快照,如果Redis因為某些原因不能正常工作,那麼從上次產生快照到Redis出現問題這段時間的資料就會丟失了。
(2)RDB使用fork()產生子程式的過程會堵塞主程式,所以資料比較大的話 fork() 可能很耗時,就會造成Redis停止服務幾毫秒。
3、AOF優點
(1)該機制可以帶來更高的資料安全性,即資料永續性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事實上,每秒同步也是非同步完成的,其效率也是非常
高的,如果發生災難,您只可能會丟失1秒的資料。
(2)AOF日誌檔案是一個純追加的檔案。就算伺服器突然Crash,也不會出現日誌的定位或者損壞問題。甚至如果因為某些原因(例如磁碟滿了)命令只寫了一半到日誌檔案裡,
我們也可以用redis-check-aof這個工具很簡單的進行修復。
(3)當AOF檔案太大時,Redis會自動在後臺進行重寫。重寫很安全,因為重寫是在一個新的檔案上進行。
4、AOF缺點
(1)在相同的資料集下,AOF檔案的大小一般會比RDB檔案大。
(2)AOF開啟後,寫QPS會比RDB的低。通常fsync設定為每秒一次就能獲得比較高的效能,而在禁止fsync的情況下速度可以達到RDB的水平。
四、生產配置持久化的一些意見
(1)官方建議:是同時開啟兩種持久化策略。因為有時需要RDB快照是進行資料庫備份,更快重啟以及發生AOF引擎錯誤的解決辦法。(換句話就是通過RDB來多備份一份資料
總是好的)
(2) 因為RDB檔案只用作後備用途,建議只在Slave上持久化RDB檔案,而且只要15分鐘備份一次就夠了,只保留save 900 1這條規則。
(3)如果選擇AOF,只要硬碟許可,應該儘量減少AOF rewrite的頻率。因為一是帶來了持續的IO,二是AOF rewrite的最後將rewrite過程中產生的新資料寫到新檔案造成的阻塞
幾乎是不可避免的。AOF重寫的基礎大小預設值64M太小了,可以設到2G以上。