文章目錄
1. 什么是Redis持久化?
持久化就是把內存的數據寫到磁盤中去,防止服務宕機了內存數據丟失。
2. Redis 的持久化機制是什么?各自的優缺點?
Redis 提供兩種持久化機制 RDB(默認) 和 AOF 機制。
2.1 RDB(Redis DataBase),快照
RDB是Redis默認的持久化方式。按照一定的時間將內存的數據以快照的形式保存到硬盤中,對應產生的數據文件為 dump.rdb
。通過配置文件中的save參數來定義快照的周期。
優點:
-
- 只有一個文件 dump.rdb,方便持久化。
-
- 容災性好,一個文件可以保存到安全的磁盤。
-
- 性能最大化,fork 子進程來完成寫操作,讓主進程繼續處理命令,所以是 IO 最大化。使用單獨子進程來進行持久化,主進程不會進行任何 IO 操作,保證了 redis 的高性能
-
- 相對于數據集大時,比 AOF 的啟動效率更高。
缺點:
-
- 數據安全性低。RDB 是間隔一段時間進行持久化,如果持久化之間 redis 發生故障,會發生數據丟失。所以這種方式更適合數據要求不嚴謹的時候)
2.2 AOF(Append Only File),日志
AOF持久化(即Append Only File持久化),則是將Redis執行的每次寫命令記錄到單獨的日志文件中,當重啟Redis會重新將持久化的日志中文件恢復數據。
所有的命令行記錄以 redis 命令請 求協議的格式完全持久化存儲)保存為 aof 文件。
當兩種方式同時開啟時,數據恢復Redis會優先選擇AOF恢復。
優點:
- 1、數據安全,aof 持久化可以配置
appendfsync
屬性,有 always,每進行一次 命令操作就記錄到 aof 文件中一次。 - 2、通過 append 模式寫文件,即使中途服務器宕機,可以通過
redis-check-aof
工具解決數據一致性問題。 - 3、AOF 機制的 rewrite 模式。AOF 文件沒被 rewrite 之前(文件過大時會對命令 進行合并重寫),可以刪除其中的某些命令(比如誤操作的 flushall))
缺點:
- 1、AOF 文件比 RDB 文件大,且恢復速度慢。
- 2、數據集大的時候,比 rdb 啟動效率低。
3. 優缺點是什么?
- AOF文件比RDB更新頻率高,優先使用AOF還原數據。
- AOF比RDB更安全也更大
- RDB性能比AOF好
- 如果兩個都配了優先加載AOF
4. 如何選擇合適的持久化方式
- 如果極度關心數據安全性,你應該同時使用兩種持久化功能。在這種情況下,當 Redis 重啟的時候會優先載入AOF 文件來恢復原始的數據,因為在通常情況下AOF文件保存的數據集要比RDB文件保存的數據集要完整。
- 如果非常關心你的數據, 但仍然可以承受數分鐘以內的數據丟失,那么你可以只使用RDB持久化。
- 如果你只希望你的數據在服務器運行的時候存在,你也可以不使用任何持久化方式。
- 有很多用戶都只使用 AOF 持久化,但并不推薦這種方式,因為定時生成 RDB 快照(snapshot)非常便于進行數據庫備份, 并且 RDB 恢復數據集的速度也要比AOF恢復的速度要快,除此之外,使用 RDB 還可以避免 AOF 程序的 bug 。
5. Redis持久化數據和緩存怎么做擴容?
- 如果Redis被當做緩存使用,使用一致性哈希實現動態擴容縮容。
- 如果Redis被當做一個持久化存儲使用,必須使用固定的 keys-to-nodes 映射關系,節點的數量一旦確定不能變化。否則的話( 即Redis節點需要動態變化的情況 ),必須使用可以在運行時進行數據再平衡的一套系統,而當前只有Redis集群可以做到這樣。
6. Redis 怎么確保 Aof 不丟失
首先,要 AOF
完全不丟失,是不可能的,因為 aof 的寫回策略只有三種,always,everySec, no
,就算啟用的是 always
,由于 redis 是寫后日志,當數據寫入成功的瞬間,redis 實例宕機了,依然會導致 aof 丟失,但是此時,redis 沒有響應,所以可以認為 aof 不曾丟失(因為業務沒有成功響應)。
7. Aof 日志是寫前還是寫后日志
說到日志,我們比較熟悉的是數據庫的寫前日志(Write Ahead Log, WAL),也就是說,在實際寫數據前,先把修改的數據記到日志文件中,以便故障時進行恢復。不過,AOF日志正好相反,它是寫后日志,“寫后”的意思是Redis是先執行命令,把數據寫入內存,然后才記錄日志。
8. AOF為什么要先執行命令再記日志
要回答這個問題,我們要先知道AOF里記錄了什么內容。
傳統數據庫的日志,例如redo log(重做日志),記錄的是修改后的數據,而AOF里記錄的是Redis收到的每一條命令,這些命令是以文本形式保存的。
我們以Redis收到“ set testkey testvalue ”命令后記錄的日志為例,看看 AOF 日志的內容。其中,“*3”表示當前命令有三個部分,每部分都是由“$+數字”開頭,后面緊跟著具體的命令、鍵或值。這里,“數字”表示這部分中的命令、鍵或值一共有多少字節。例如,“$3 set”表示這部分有3個字節,也就是“set”命令。
最重要的原因是 Redis 作為一個內存數據庫追求極致的性能。
為了避免額外的檢查開銷,Redis在向AOF里面記錄日志的時候,并不會先去對這些命令進行語法檢查。所以,如果先記日志再執行命令的話,日志中就有可能記錄了錯誤的命令,Redis在使用日志恢復數據時,就可能會出錯。
而寫后日志這種方式,就是先讓系統執行命令,只有命令能執行成功,才會被記錄到日志中,否則,系統就會直接向客戶端報錯。所以,Redis使用寫后日志這一方式的一大好處是,可以避免出現記錄錯誤命令的情況。
除此之外,AOF還有一個好處:它是在命令執行后才記錄日志,所以不會阻塞當前的寫操作。
9. Redis Aof 的風險
AOF也有兩個潛在的風險。
首先,如果剛執行完一個命令,還沒有來得及記日志就宕機了,那么這個命令和相應的數據就有丟失的風險。如果此時Redis是用作緩存,還可以從后端數據庫重新讀入數據進行恢復,但是,如果Redis是直接用作數據庫的話,此時,因為命令沒有記入日志,所以就無法用日志進行恢復了。
其次,AOF雖然避免了對當前命令的阻塞,但可能會給下一個操作帶來阻塞風險。這是因為,AOF日志也是在主線程中執行的,如果在把日志文件寫入磁盤時,磁盤寫壓力大,就會導致寫盤很慢,進而導致后續的操作也無法執行了。
仔細分析的話,你就會發現,這兩個風險都是和AOF寫回磁盤的時機相關的。這也就意味著,如果我們能夠控制一個寫命令執行完后AOF日志寫回磁盤的時機,這兩個風險就解除了。