一、簡介
Redis是一種高級key-value數據庫。它跟memcached類似,不過數據可以持久化,而且支持的數據類型很豐富。有字符串,鏈表,集 合和有序集合。支持在服務器端計算集合的並,交和補集(difference)等,還支持多種排序功能。所以Redis也可以被看成是一個數據結構服務 器。
Redis的所有數據都是保存在內存中,然后不定期的通過異步方式保存到磁盤上(這稱為“半持久化模式”);也可以把每一次數據變化都寫入到一個append only file(aof)里面(這稱為“全持久化模式”)。
由於Redis的數據都存放在內存中,如果沒有配置持久化,redis重啟后數據就全丟失了,於是需要開啟redis的持久化功能,將數據保存到磁 盤上,當redis重啟后,可以從磁盤中恢復數據。redis提供兩種方式進行持久化,一種是RDB持久化(原理是將Reids在內存中的數據庫記錄定時 dump到磁盤上的RDB持久化),另外一種是AOF(append only file)持久化(原理是將Reids的操作日志以追加的方式寫入文件)。那么這兩種持久化方式有什么區別呢,改如何選擇呢?網上看了大多數都是介紹這兩 種方式怎么配置,怎么使用,就是沒有介紹二者的區別,在什么應用場景下使用。
Redis 提供了多種不同級別的持久化方式:
1 RDB 持久化可以在指定的時間間隔內生成數據集的時間點快照(point-in-time snapshot)。 2 AOF 持久化記錄服務器執行的所有寫操作命令,並在服務器啟動時,通過重新執行這些命令來還原數據集。 AOF 文件中的命令全部以 Redis 協議的格式來保存,新命令會被追加到文件的末尾。 Redis 還可以在后台對 AOF 文件進行重寫(rewrite),使得 AOF 文件的體積不會超出保存數據集狀態所需的實際大小。 3 Redis 還可以同時使用 AOF 持久化和 RDB 持久化。 在這種情況下, 當 Redis 重啟時, 它會優先使用 AOF 文件來還原數據集, 因為 AOF 文件保存的數據集通常比 RDB 文件所保存的數據集更完整。 4 你甚至可以關閉持久化功能,讓數據只在服務器運行時存在
二、區別
RDB持久化是指在指定的時間間隔內將內存中的數據集快照寫入磁盤,實際操作過程是fork一個子進程,先將數據集寫入臨時文件,寫入成功后,再替換之前的文件,用二進制壓縮存儲。
AOF持久化以日志的形式記錄服務器所處理的每一個寫、刪除操作,查詢操作不會記錄,以文本的方式記錄,可以打開文件看到詳細的操作記錄。
三、二者優缺點
RDB存在哪些優勢呢?
1). 一旦采用該方式,那么你的整個Redis數據庫將只包含一個文件,這對於文件備份而言是非常完美的。比如,你可能打算每個小時歸檔一次最近24小時的數 據,同時還要每天歸檔一次最近30天的數據。通過這樣的備份策略,一旦系統出現災難性故障,我們可以非常容易的進行恢復。 2). 對於災難恢復而言,RDB是非常不錯的選擇。因為我們可以非常輕松的將一個單獨的文件壓縮后再轉移到其它存儲介質上。 3). 性能最大化。對於Redis的服務進程而言,在開始持久化時,它唯一需要做的只是fork出子進程,之后再由子進程完成這些持久化的工作,這樣就可以極大的避免服務進程執行IO操作了。 4). 相比於AOF機制,如果數據集很大,RDB的啟動效率會更高。
RDB又存在哪些劣勢呢?
1). 如果你想保證數據的高可用性,即最大限度的避免數據丟失,那么RDB將不是一個很好的選擇。因為系統一旦在定時持久化之前出現宕機現象,此前沒有來得及寫入磁盤的數據都將丟失。
2). 由於RDB是通過fork子進程來協助完成數據持久化工作的,因此,如果當數據集較大時,可能會導致整個服務器停止服務幾百毫秒,甚至是1秒鍾。
AOF的優勢有哪些呢?
1). 該機制可以帶來更高的數據安全性,即數據持久性。Redis中提供了3中同步策略,即每秒同步、每修改同步和不同步。事實上,每秒同步也是異步完成的,其 效率也是非常高的,所差的是一旦系統出現宕機現象,那么這一秒鍾之內修改的數據將會丟失。而每修改同步,我們可以將其視為同步持久化,即每次發生的數據變 化都會被立即記錄到磁盤中。可以預見,這種方式在效率上是最低的。至於無同步,無需多言,我想大家都能正確的理解它。 2). 由於該機制對日志文件的寫入操作采用的是append模式,因此在寫入過程中即使出現宕機現象,也不會破壞日志文件中已經存在的內容。然而如果我們本次操 作只是寫入了一半數據就出現了系統崩潰問題,不用擔心,在Redis下一次啟動之前,我們可以通過redis-check-aof工具來幫助我們解決數據 一致性的問題。 3). 如果日志過大,Redis可以自動啟用rewrite機制。即Redis以append模式不斷的將修改數據寫入到老的磁盤文件中,同時Redis還會創 建一個新的文件用於記錄此期間有哪些修改命令被執行。因此在進行rewrite切換時可以更好的保證數據安全性。 4). AOF包含一個格式清晰、易於理解的日志文件用於記錄所有的修改操作。事實上,我們也可以通過該文件完成數據的重建。
AOF的劣勢有哪些呢?
1). 對於相同數量的數據集而言,AOF文件通常要大於RDB文件。RDB 在恢復大數據集時的速度比 AOF 的恢復速度要快。
2). 根據同步策略的不同,AOF在運行效率上往往會慢於RDB。總之,每秒同步策略的效率是比較高的,同步禁用策略的效率和RDB一樣高效。
二者選擇的標准,就是看系統是願意犧牲一些性能,換取更高的緩存一致性(aof),還是願意寫操作頻繁的時候,不啟用備份來換取更高的性能,待手動運行save的時候,再做備份(rdb)。rdb這個就更有些 eventually consistent的意思了。
四、配置
RDB方式
Redis通過創建快照的方式獲取某一時刻Redis中所有數據的副本。用戶可以針對該快照進行各種操作,比如:將快照復制到其他服務器從而完成Redis的主從復制,或者將快照留在原地,服務器重啟的時候重用數據。
根據配置文件,可以手動設置Redis快照名及路徑:
1 # RDB文件名 2 dbfilename "dump.rdb" 3# RDB文件和AOF文件路徑 4dir "/usr/local/var/db/redis"
Redis創建快照主要有以下幾種方式:
(1)客戶端直接通過命令BGSAVE或者SAVE來創建一個快照
1 - BGSAVE是通過redis調用fork來創建一個子進程,然后子進程負責將快照寫入磁盤,而父進程仍然繼續處理命令。 2 - SAVE是在沒有足夠的內存空間去執行BGSAVE或者無所謂等待的時候。執行SAVE命令過程中,redis不在響應任何其他命令。
(2)在redis.conf中設置save配置選項(應用開發中比較常用)
1 # 當在規定的時間內,Redis發生了寫操作的個數滿足條件,會觸發發生BGSAVE命令。 2 # save <seconds> <changes> 3 # 當用戶設置了多個save的選項配置,只要其中任一條滿足,Redis都會觸發一次BGSAVE操作,比如:900秒之內至少一次寫操作、300秒之內至少發生10次寫操作、60秒之內發生至少10000次寫操作都會觸發發生快照操作 4 save 900 1 5 save 300 10 6 save 60 10000
(3)當Redis通過shutdown命令關閉服務器請求時,會執行SAVE命令創建一個快照,如果使用kill -9 PID將不會創建快照。
注意:
1 在只使用快照持久化來報錯數據時,如果系統崩潰或者強殺,用戶將會丟失最近一次生成快照之后更改的所有數據。因此如果應用程序對於兩次快照間丟失的數據可接受,利用快照就是一個很好的方式,但是往往一些系統對於丟失幾分鍾的數據都不可接受,比如高頻的電子商務系統。 2 此外,如果Redis存儲的數據量長達數十G的時候,沒執行一次快照需要花費大量時間,嚴重影響到服務器的性能。
AOF方式
在執行寫命令時,AOF持久化會將執行的寫命令也寫到AOF文件的末尾,以此來記錄數據的變化。換句話說,將AOF文件中包含的內容重新執行一遍,就可以回復AOF文件所記錄的數據集。
在Redis.conf配置中設置如下:
1 # redis默認關閉AOF機制,可以將no改成yes實現AOF持久化 2 appendonly no 3 # AOF文件 4 appendfilename "appendonly.aof" 5 # AOF持久化同步頻率,always表示每個Redis寫命令都要同步fsync寫入到磁盤中,但是這種方式會嚴重降低redis的速度;everysec表示每秒執行一次同步fsync,顯示的將多個寫命令同步到磁盤中;no表示讓操作系統來決定應該何時進行同步fsync,Linux系統往往可能30秒才會執行一次 6 # appendfsync always 7 appendfsync everysec 8 # appendfsync no 9 10 # 在日志進行BGREWRITEAOF時,如果設置為yes表示新寫操作不進行同步fsync,只是暫存在緩沖區里,避免造成磁盤IO操作沖突,等重寫完成后在寫入。redis中默認為no 11 no-appendfsync-on-rewrite no 12 # 當前AOF文件大小是上次日志重寫時的AOF文件大小兩倍時,發生BGREWRITEAOF操作。 13 auto-aof-rewrite-percentage 100 14 #當前AOF文件執行BGREWRITEAOF命令的最小值,避免剛開始啟動Reids時由於文件尺寸較小導致頻繁的BGREWRITEAOF。 15 auto-aof-rewrite-min-size 64mb 16 # Redis再恢復時,忽略最后一條可能存在問題的指令(因為最后一條指令可能存在問題,比如寫一半時突然斷電了) 17 aof-load-truncated yes 18 #Redis4.0新增RDB-AOF混合持久化格式,在開啟了這個功能之后,AOF重寫產生的文件將同時包含RDB格式的內容和AOF格式的內容,其中RDB格式的內容用於記錄已有的數據,而AOF格式的內存則用於記錄最近發生了變化的數據,這樣Redis就可以同時兼有RDB持久化和AOF持久化的優點(既能夠快速地生成重寫文件,也能夠在出現問題時,快速地載入數據)。 19 aof-use-rdb-preamble no
RDB與AOF同時開啟 默認先加載AOF的配置文件,因此需要根據具體情況使用,4.0+的可以使用RDB-AOF混合持久化格式