Redis的數據是存儲在內存中的,內存中的數據隨着服務器的重啓或者宕機便會不復存在,在生產環境,服務器宕機更是家常便飯,因此,咱們但願Redis可以將數據從內存中以某種形式保存到磁盤中,使得重啓的時候能夠加載磁盤中的文件記錄恢復數據,這一過程即是Redis的持久化。
Redis支持兩種持久化機制,一種是RDB,另外一種是AOF。Redis默認狀況下使用RDB方式進行持久化。兩種持久化能夠單獨使用其中的一種,也能夠兩者結合使用,下面便來分別介紹下這兩種持久化機制。html
RDB方式的持久化是經過快照(snapshotting)方式完成的,當符合必定條件的時候redis會自動將內存中的數據生成一份副本存儲在磁盤中,這個過程即爲「快照」。
Redis會根據如下幾種狀況對數據進行快照:redis
用戶能夠自定義快照條件,當符合快照條件,Redis便會執行快照操做,在redis.conf配置文件中,有這麼一段配置及說明:數據庫
It is also possible to remove all the previously configured save # points by adding a save directive with a single empty string argument # like in the following example: # # save "" save 900 1 save 300 10 save 60 10000 # By default Redis will stop accepting writes if RDB snapshots are enabled # (at least one save point) and the latest background save failed. # This will make the user aware (in a hard way) that data is not persisting # on disk properly, otherwise chances are that no one will notice and some # disaster will happen.
在save命令後面加上兩個數字,save <指定時間間隔> <執行指定次數更新操做> 。例如:save 900 1 表示在900秒內有一個或者一個以上的鍵被更改時即執行快照操做。 promise
一、save命令
執行save命令時redis會同步執行快照操做,這將會阻塞全部來自客戶端的請求,服務器沒法響應其餘的處理,直到執行完成爲止。若是數據量小,用此命令可能感受不出有什麼區別,可是當數據量很大的時候,就須要謹慎使用這個命令。
二、bgasve命令
執行bgsave命令時,redis會fork出一個子進程去完成備份的操做,不會影響redis處理其餘的請求。緩存
執行FLUSHALL命令時,Redis會清除數據庫中的全部數據,不論清空數據庫的過程是否觸發了自動快照條件,只要快照條件存在,就會執行快照操做,當沒有快照條件時,執行FLUSHALL不會進行快照。安全
當設置了主從模式時,Redis會在複製初始化時進行自動快照,即便沒有設置自動快照條件時,也會執行快照操做。服務器
存儲路徑:
Redis默認將快照文件保存在Redis當前進程的工做目錄中的dump.rdb文件中,能夠經過配置dir和dbfilename兩個參數分別制定快照文案件的存儲路徑和文件名。如redis.conf文件中的配置和註釋:數據結構
# The filename where to dump the DB dbfilename dump.rdb # The working directory. # DB將以dbfilename指定文件名被寫入這個目錄中, # The DB will be written inside this directory, with the filename specified # above using the 'dbfilename' configuration directive. # Note that you must specify a directory here, not a file name. dir ./
redis在執行快照的過程當中不會修改RDB文件,在快照結束後纔會進行替換。所以RDB文件一般也用來實現Redis的數據備份,而且RDB文件是通過壓縮的二進制格式,因此佔用空間比內存中的數據小。app
Redis啓動後會讀取RDB文件,將數據從磁盤加載到內存,一般將一個記錄了1000萬字符串類型鍵、大小爲1GB的快照文件載入內存須要20~30秒,載入的時間根據不一樣的服務器性能和Redis的數據結構而不一樣。ide
RDB 的優缺點
優勢:
1 適合大規模的數據恢復。
2 若是業務對數據完整性和一致性要求不高,RDB是很好的選擇。
缺點:
1 數據的完整性和一致性不高,由於RDB可能在最後一次備份時宕機了。
2 備份時佔用內存,由於Redis 在備份時會獨立建立一個子進程,將數據寫入到一個臨時文件(此時內存中的數據是原來的兩倍哦),最後再將臨時文件替換以前的備份文件。
爲了下降由於進程終止致使的數據丟失的風險,Redis還提供了AOF的方式來進行持久化,AOF能夠將Redis執行的每一條命令追加到硬盤文件中,這一過程會下降redis的性能,但從數據的安全性來講,這個影響是能夠接受的。
AOF文件的保存地址和RDB文件位置相同,都是經過dir參數設置,默認文件名爲appendonly.aof。
以下所示:
appendonly no # The name of the append only file (default: "appendonly.aof") appendfilename "appendonly.aof"
默認狀況下,Redis沒有開啓AOF的方式,可經過修改redis.conf配置文件中的appendonly參數爲yes進行啓動。
若是尚未生成aof文件的話,可使用命令設置:
./redis-cli config set appendonly yes
aof文件打開是這樣的:
*2 $6 SELECT $1 0 *3 $3 SET $3 age $2 28 *3 $3 SET $2 cc $2 vv
AOF文件以純文本的形式記錄了Redis的執行命令,AOF文件中的內容是Redis客戶端向Redis發送的原始通訊協議的內容,當對相同key進行屢次賦值操做時,aof也會將這些命令記錄下來,但其實咱們只但願它記錄最後一次的值,爲此Redis在redis.conf文件中提供了這樣的參數來自動重寫AOF文件:
# 當目前的AOF文件大小超過上一次重寫的AOF文件大小的百分之多少進行重寫 auto-aof-rewrite-percentage 100 # 容許重寫的AOF的最小AOF文件大小 auto-aof-rewrite-min-size 64mb
Redis在啓動的時候會逐條執行AOF文件中的命令來將硬盤中的文件寫入到內存中,所以載入的速度相對慢些。
# The fsync() call tells the Operating System to actually write data on disk # instead of waiting for more data in the output buffer. Some OS will really flush # data on disk, some other OS will just try to do it ASAP. # # Redis supports three different modes: # # no: don't fsync, just let the OS flush the data when it wants. Faster. # always: fsync after every write to the append only log. Slow, Safest. # everysec: fsync only one time every second. Compromise. # The default is "everysec", as that's usually the right compromise between # speed and data safety. It's up to you to understand if you can relax this to # "no" that will let the operating system flush the output buffer when # it wants, for better performances (but if you can live with the idea of # some data loss consider the default persistence mode that's snapshotting), # or on the contrary, use "always" that's very slow but a bit safer than # everysec. # # More details please check the following article: # http://antirez.com/post/redis-persistence-demystified.html # # If unsure, use "everysec". # appendfsync always appendfsync everysec # appendfsync no
而且咱們須要注意的是下面這段描述:
The fsync() call tells the Operating System to actually write data on disk # instead of waiting for more data in the output buffer. Some OS will really flush # data on disk, some other OS will just try to do it ASAP.
雖然每次更改數據庫內容的操做時,redis都會把更新記錄在AOF文件中,可是因爲操做系統的緩存機制,數據並無真正的寫入磁盤,而是進入了系統硬盤緩存。在默認狀況下會每30秒執行一次同步操做,若是在這30秒以內系統異常會致使硬盤緩存中的數據丟失,咱們使用AOF命令的方式就是爲了儘量的減小數據的丟失,因此redis提供了appendfsync參數來設置同步機制。默認狀況下使用everysec,即每秒執行一次同步操做,將數據從緩存更新到磁盤中。always表示每次執行寫入都會執行同步操做,這是最慢也是最安全的方式。no表示不主動執行,交由操做系統執行,這是最不安全的方式。通常狀況下兼顧系統性能,使用everysec的方式便可。
優勢:數據的完整性和一致性更高
缺點:由於AOF記錄的內容多,文件會愈來愈大,數據恢復也會愈來愈慢。
RDB和AOF能夠同時存在,這樣既保證了數據安全又使得進行備份操做十分容易,Redis會使用AOF文件來恢復數據,由於AOF的方式持久化丟失的數據會更少。