Redis持久化

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

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

補充:Redis 的存儲分爲內存存儲磁盤存儲log文件三部分,配置文件中有三個參數對其進行配置。redis

save seconds updates:在指定時間內,達到多少次更新操做時,就將數據同步到數據文件。這個能夠多個條件配合,好比默認配置文件中的設置,就設置了三個條件。sql

appendonly yes/no:是否在每次更新操做後進行日誌記錄,若是不開啓,可能會在斷電時致使一段時間內的數據丟失。由於redis自己同步數據文件是按上面的save條件來同步的,因此有的數據會在一段時間內只存在於內存中。緩存

appendfsyncno/always/everysec:no表示等操做系統進行數據緩存同步到磁盤,always表示每次更新操做後手動調用fsync()將數據寫到磁盤,everysec表示每秒同步一次。安全

1、RDBruby

工做原理服務器

  • Redis調用fork(),產生一個子進程。
  • 子進程把數據寫到一個臨時的RDB文件。
  • 當子進程寫完新的RDB文件後,把舊的RDB文件替換掉。

優勢app

  • 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 <seconds> <changes> # 能夠設置多個。 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 

配置文件裏禁用了快照生成功能不影響SAVEBGSAVE命令的效果

2、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的文件,並把備份文件放在一個安全的地方。
  • 運行如下兩條命令:

    $ redis-cli config set appendonly yes $ redis-cli config set save "" 
  • 確保數據跟切換前一致。

  • 確保數據正確的寫到AOF文件裏。

第二條命令是用來禁用RDB的持久化方式,可是這不是必須的,由於你能夠同時啓用兩種持久化方式。

記得對配置文件redis.conf進行編輯啓用AOF,由於命令行方式修改配置在重啓Redis後就會失效。

    Redis 配置文件默認狀況下是開啓 rdb模式的寫入磁盤備份的.

    1.默認開啓的狀況下是使用Master傳輸rdb文件到slave進行主從同步。

    2.禁用rdb和aof模式在不生成rdb文件的狀況下也能夠實現主從同步,前提是master,slave服務器都在運行中的時候,這個種狀況下master只是把緩衝區中的set 操做傳輸到slave端,slave端再執行set命令實現主從同步。

   3.當禁用master,slave rdb模式的狀況下,shutdown slave 端,再重啓時,會去鏈接master端同步數據,master端會生成dump.rdb文件,而後傳給slave端,salve端同時也會生成dump.rdb文件。

   總結:master,slvae端能夠在配置文件中能夠禁用rdb模式,這時數據只存在內存中。當slave 端重起時,會鏈接master端,maser端會把內存中數據生成到dump.rdb文件,而後把rdb文件和緩衝區中的set命令而後傳給slave,slave也會生成dump.rdb文件。若是master服務先掛了,那麼就是災難性的了。由於這個時候master端尚未dump.rdb文件,服務啓動後找不到rdb文件載入到內存中。slave端會去鏈接master端同步數據,把空數據同步回來覆蓋原先的已有數據。形成master,slvae端都沒有了緩存數據。

相關文章
相關標籤/搜索