1. 程式人生 > >redis---Redis持久化

redis---Redis持久化

轉自:https://segmentfault.com/a/1190000002906345

Redis的持久化

Redis有兩種持久化的方式:快照(RDB檔案)和追加式檔案(AOF檔案):

RDB持久化方式會在一個特定的間隔儲存那個時間點的一個數據快照。
AOF持久化方式則會記錄每一個伺服器收到的寫操作。在服務啟動時,這些記錄的操作會逐條執行從而重建出原來的資料。寫操作命令記錄的格式跟Redis協議一致,以追加的方式進行儲存。
Redis的持久化是可以禁用的,就是說你可以讓資料的生命週期只存在於伺服器的執行時間裡。
兩種方式的持久化是可以同時存在的,但是當Redis重啟時,AOF檔案會被優先用於重建資料。
RDB

工作原理

Redis呼叫fork(),產生一個子程序。
子程序把資料寫到一個臨時的RDB檔案。
當子程序寫完新的RDB檔案後,把舊的RDB檔案替換掉。
優點
RDB檔案是一個很簡潔的單檔案,它儲存了某個時間點的Redis資料,很適合用於做備份。你可以設定一個時間點對RDB檔案進行歸檔,這樣就能在需要的時候很輕易的把資料恢復到不同的版本。
基於上面所描述的特性,RDB很適合用於災備。單檔案很方便就能傳輸到遠端的伺服器上。
RDB的效能很好,需要進行持久化時,主程序會fork一個子程序出來,然後把持久化的工作交給子程序,自己不會有相關的I/O操作。
比起AOF,在資料量比較大的情況下,RDB的啟動速度更快。
缺點
RDB容易造成資料的丟失。假設每5分鐘儲存一次快照,如果Redis因為某些原因不能正常工作,那麼從上次產生快照到Redis出現問題這段時間的資料就會丟失了。
RDB使用fork()產生子程序進行資料的持久化,如果資料比較大的話可能就會花費點時間,造成Redis停止服務幾毫秒。如果資料量很大且CPU效能不是很好的時候,停止服務的時間甚至會到1秒。
檔案路徑和名稱
預設Redis會把快照檔案儲存為當前目錄下一個名為dump.rdb的檔案。要修改檔案的儲存路徑和名稱,可以通過修改配置檔案redis.conf實現:

RDB檔名,預設為dump.rdb。
dbfilename dump.rdb

檔案存放的目錄,AOF檔案同樣存放在此目錄下。預設為當前工作目錄。
dir ./
儲存點(RDB的啟用和禁用)
你可以配置儲存點,使Redis如果在每N秒後資料發生了M次改變就儲存快照檔案。例如下面這個儲存點配置表示每60秒,如果資料發生了1000次以上的變動,Redis就會自動儲存快照檔案:

save 60 1000
儲存點可以設定多個,Redis的配置檔案就預設設定了3個儲存點:

格式為:save
可以設定多個。
save 900 1 #900秒後至少1個key有變動
save 300 10 #300秒後至少10個key有變動
save 60 10000 #60秒後至少10000個key有變動
如果想禁用快照儲存的功能,可以通過註釋掉所有”save”配置達到,或者在最後一條”save”配置後新增如下的配置:

save “”
錯誤處理
預設情況下,如果Redis在後臺生成快照的時候失敗,那麼就會停止接收資料,目的是讓使用者能知道資料沒有持久化成功。但是如果你有其他的方式可以監控到Redis及其持久化的狀態,那麼可以把這個功能禁止掉。

stop-writes-on-bgsave-error yes
資料壓縮
預設Redis會採用LZF對資料進行壓縮。如果你想節省點CPU的效能,你可以把壓縮功能禁用掉,但是資料集就會比沒壓縮的時候要打。

rdbcompression yes
資料校驗
從版本5的RDB的開始,一個CRC64的校驗碼會放在檔案的末尾。這樣更能保證檔案的完整性,但是在儲存或者載入檔案時會損失一定的效能(大概10%)。如果想追求更高的效能,可以把它禁用掉,這樣檔案在寫入校驗碼時會用0替代,載入的時候看到0就會直接跳過校驗。

rdbchecksum yes
手動生成快照
Redis提供了兩個命令用於手動生成快照。

SAVE

SAVE命令會使用同步的方式生成RDB快照檔案,這意味著在這個過程中會阻塞所有其他客戶端的請求。因此不建議在生產環境使用這個命令,除非因為某種原因需要去阻止Redis使用子程序進行後臺生成快照(例如呼叫fork(2)出錯)。

BGSAVE

BGSAVE命令使用後臺的方式儲存RDB檔案,呼叫此命令後,會立刻返回OK返回碼。Redis會產生一個子程序進行處理並立刻恢復對客戶端的服務。在客戶端我們可以使用LASTSAVE命令檢視操作是否成功。

127.0.0.1:6379> BGSAVE
Background saving started
127.0.0.1:6379> LASTSAVE
(integer) 1433936394
配置檔案裡禁用了快照生成功能不影響SAVE和BGSAVE命令的效果。

AOF

快照並不是很可靠。如果你的電腦突然宕機了,或者電源斷了,又或者不小心殺掉了程序,那麼最新的資料就會丟失。而AOF檔案則提供了一種更為可靠的持久化方式。每當Redis接受到會修改資料集的命令時,就會把命令追加到AOF檔案裡,當你重啟Redis時,AOF裡的命令會被重新執行一次,重建資料。

優點
比RDB可靠。你可以制定不同的fsync策略:不進行fsync、每秒fsync一次和每次查詢進行fsync。預設是每秒fsync一次。這意味著你最多丟失一秒鐘的資料。
AOF日誌檔案是一個純追加的檔案。就算是遇到突然停電的情況,也不會出現日誌的定位或者損壞問題。甚至如果因為某些原因(例如磁碟滿了)命令只寫了一半到日誌檔案裡,我們也可以用redis-check-aof這個工具很簡單的進行修復。
當AOF檔案太大時,Redis會自動在後臺進行重寫。重寫很安全,因為重寫是在一個新的檔案上進行,同時Redis會繼續往舊的檔案追加資料。新檔案上會寫入能重建當前資料集的最小操作命令的集合。當新檔案重寫完,Redis會把新舊檔案進行切換,然後開始把資料寫到新檔案上。
AOF把操作命令以簡單易懂的格式一條接一條的儲存在檔案裡,很容易匯出來用於恢復資料。例如我們不小心用FLUSHALL命令把所有資料刷掉了,只要檔案沒有被重寫,我們可以把服務停掉,把最後那條命令刪掉,然後重啟服務,這樣就能把被刷掉的資料恢復回來。
缺點
在相同的資料集下,AOF檔案的大小一般會比RDB檔案大。
在某些fsync策略下,AOF的速度會比RDB慢。通常fsync設定為每秒一次就能獲得比較高的效能,而在禁止fsync的情況下速度可以達到RDB的水平。
在過去曾經發現一些很罕見的BUG導致使用AOF重建的資料跟原資料不一致的問題。
啟用AOF
把配置項appendonly設為yes:

appendonly yes
檔案路徑和名稱
檔案存放目錄,與RDB共用。預設為當前工作目錄。
dir ./

預設檔名為appendonly.aof
appendfilename “appendonly.aof”
可靠性
你可以配置Redis呼叫fsync的頻率,有三個選項:

每當有新命令追加到AOF的時候呼叫fsync。速度最慢,但是最安全。
每秒fsync一次。速度快(2.4版本跟快照方式速度差不多),安全性不錯(最多丟失1秒的資料)。
從不fsync,交由系統去處理。這個方式速度最快,但是安全性一般。
推薦使用每秒fsync一次的方式(預設的方式),因為它速度快,安全性也不錯。相關配置如下:

appendfsync always
appendfsync everysec
appendfsync no
日誌重寫
隨著寫操作的不斷增加,AOF檔案會越來越大。例如你遞增一個計數器100次,那麼最終結果就是資料集裡的計數器的值為最終的遞增結果,但是AOF檔案裡卻會把這100次操作完整的記錄下來。而事實上要恢復這個記錄,只需要1個命令就行了,也就是說AOF檔案裡那100條命令其實可以精簡為1條。所以Redis支援這樣一個功能:在不中斷服務的情況下在後臺重建AOF檔案。

工作原理如下:

Redis呼叫fork(),產生一個子程序。
子程序把新的AOF寫到一個臨時檔案裡。
主程序持續把新的變動寫到記憶體裡的buffer,同時也會把這些新的變動寫到舊的AOF裡,這樣即使重寫失敗也能保證資料的安全。
當子程序完成檔案的重寫後,主程序會獲得一個訊號,然後把記憶體裡的buffer追加到子程序生成的那個新AOF裡。
Redis
我們可以通過配置設定日誌重寫的條件:

Redis會記住自從上一次重寫後AOF檔案的大小(如果自Redis啟動後還沒重寫過,則記住啟動時使用的AOF檔案的大小)。
如果當前的檔案大小比起記住的那個大小超過指定的百分比,則會觸發重寫。
同時需要設定一個檔案大小最小值,只有大於這個值檔案才會重寫,以防檔案很小,但是已經達到百分比的情況。

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
要禁用自動的日誌重寫功能,我們可以把百分比設定為0:

auto-aof-rewrite-percentage 0
Redis 2.4以上才可以自動進行日誌重寫,之前的版本需要手動執行BGREWRITEAOF這個命令。
資料損壞修復
如果因為某些原因(例如伺服器崩潰)AOF檔案損壞了,導致Redis載入不了,可以通過以下方式進行修復:

備份AOF檔案。
使用redis-check-aof命令修復原始的AOF檔案:
$ redis-check-aof –fix
可以使用diff -u命令看下兩個檔案的差異。
使用修復過的檔案重啟Redis服務。
從RDB切換到AOF
這裡只說Redis >= 2.2版本的方式:

備份一個最新的dump.rdb的檔案,並把備份檔案放在一個安全的地方。
執行以下兩條命令:
rediscliconfigsetappendonlyyes redis-cli config set save “”
確保資料跟切換前一致。
確保資料正確的寫到AOF檔案裡。
第二條命令是用來禁用RDB的持久化方式,但是這不是必須的,因為你可以同時啟用兩種持久化方式。
記得對配置檔案redis.conf進行編輯啟用AOF,因為命令列方式修改配置在重啟Redis後就會失效。
備份
建議的備份方法:
建立一個定時任務,每小時和每天建立一個快照,儲存在不同的資料夾裡。
定時任務執行時,把太舊的檔案進行刪除。例如只保留48小時的按小時建立的快照和一到兩個月的按天建立的快照。
每天確保一次把快照檔案傳輸到資料中心外的地方進行儲存,至少不能儲存在Redis服務所在的伺服器。