1. 程式人生 > 實用技巧 >redis-持久化

redis-持久化

redis-持久化

​ redis是一個記憶體資料庫,資料是儲存在記憶體中的,記憶體中的資料變化是很快的,比如伺服器出現宕機或者重啟,redis應用掛了,那麼資料就丟失了,這個是很嚴重的問題。redis提供了兩種持有化的方式來解決這個問題,RDB(Redis DateBase)和AOF(Append Only File)。

RDB持久化

​ RDB持久化方式能夠在指定的時間間隔能對你的資料進行快照儲存在硬碟中,Redis對資料進行快照的方式可分為自動快照和手動快照兩部分。

自動快照

自動快照是使用者在redis.conf檔案中配置save m n 定時觸發的,這個配置的條件是可以同時存在多個的,比如在配置檔案中預設定義了3個save配置

save 900 1
save 300 10
save 60 10000

比如 save 900 1 表示的是15分鐘有一個或者一個以上的鍵被修改則生成快照,同理save 300 10 表示5分鐘內有10個或者10以上的鍵被修改則生成快照。

手動快照

顧名思義手動快照就是通過手動輸入命令來進行快照生成,主要通過save和bgsave來手動讓Redis進行資料集儲存操作。

save

當執行save命令時,redis同步的進行快照操作,在快照執行的過程中會阻塞所有來自客戶端的請求。如果資料庫中資料比較多的時候,最好不要使用save命令來執行,因為時同步操作,會影響使用者體驗

bgsave

bgsave命令可以在後臺非同步地進行快照操作,快照的同時伺服器還可以繼續響應客戶端的請求。執行完bgsave命令,redis會立即返回ok表示執行快照開始,同時可以通過lastsave命令來查詢快照是否完成,返回的是時間戳。如果需要手動執行快照操作,推薦使用bgsave命令來執行。

快照原理

Redis 需要儲存 dump.rdb 檔案時, 伺服器執行以下操作:

  • Redis 呼叫forks. 同時擁有父程序和子程序。
  • 子程序將資料集寫入到一個臨時 RDB 檔案中。
  • 當子程序完成對新 RDB 檔案的寫入時,Redis 用新 RDB 檔案替換原來的 RDB 檔案,並刪除舊的 RDB 檔案。
RDB配置
#只要滿足以下的條件就會進行自動生成快照
#15分鐘有一個或者一個以上的鍵被修改,則執行
save 900 1 
save 300 10
save 60 10000

#禁用RDB
save ""

#當備份程序出錯時,主程序是否停止寫操作
stop-writes-on-bgsave-error yes

#是否壓縮rdb檔案 推薦no 相對於硬碟成本cpu資源更貴
rdbcompression no

AOF持久化

AOF(Append-Only-File)持久化的記錄redis執行的每一條命令,通過append將執行的命令追加儲存到AOF檔案中。

AOF配置
# 預設關閉AOF,若要開啟將no改為yes
appendonly no

# append檔案的名字
appendfilename "appendonly.aof"

# 每隔一秒將快取區內容寫入檔案 預設開啟的寫入方式
appendfsync everysec

# 當AOF檔案大小的增長率大於該配置項時自動開啟重寫(這裡指超過原大小的100%)。
auto-aof-rewrite-percentage 100

# 當AOF檔案大小大於該配置項時自動開啟重寫
auto-aof-rewrite-min-size 64mb
AOF持久化原理
  • 將指令寫到AOF緩衝區
  • 從AOF緩衝區append到AOF檔案
  • 從AOF檔案儲存到磁碟中
AOF寫入緩衝區的方式

AOF寫入緩衝區的方式有三種,通過appendfsync配置來修改,預設時everysec,每個一秒同步一次

always:每次有新命令追加到 AOF 檔案時就執行一次 fsync :非常慢,也非常安全

everysec:每秒 fsync 一次:足夠快(和使用 RDB 持久化差不多),並且在故障時只會丟失 1 秒鐘的資料

no:將資料交給作業系統來處理。更快,也更不安全的選擇。

推薦(並且也是預設)的措施為每秒 fsync 一次, 這種 fsync 策略可以兼顧速度和安全性。

AOF工作原理
  • Redis 執行 fork() ,現在同時擁有父程序和子程序。
  • 子程序開始將新 AOF 檔案的內容寫入到臨時檔案。
  • 對於所有新執行的寫入命令,父程序一邊將它們累積到一個記憶體快取中,一邊將這些改動追加到現有 AOF 檔案的末尾,這樣樣即使在重寫的中途發生停機,現有的 AOF 檔案也還是安全的。
  • 當子程序完成重寫工作時,它給父程序傳送一個訊號,父程序在接收到訊號之後,將記憶體快取中的所有資料追加到新 AOF 檔案的末尾。
  • 搞定!現在 Redis 原子地用新檔案替換舊檔案,之後所有命令都會直接追加到新 AOF 檔案的末尾。
AOF檔案恢復

伺服器可能在程式正在對 AOF 檔案進行寫入時停機, 如果停機造成了 AOF 檔案出錯(corrupt), 那麼 Redis 在重啟時會拒絕載入這個 AOF 檔案, 從而確保資料的一致性不會被破壞。

  • 為現有的 AOF 檔案建立一個備份。

  • 使用 Redis 附帶的 redis-check-aof 程式,對原來的 AOF 檔案進行修復:

    $ redis-check-aof –fix

  • (可選)使用 diff -u 對比修復後的 AOF 檔案和原始 AOF 檔案的備份,檢視兩個檔案之間的不同之處。

  • 重啟 Redis 伺服器,等待伺服器載入修復後的 AOF 檔案,並進行資料恢復。

RDB和AOF優缺點

RDB優缺點

  • 優點:與AOF相比,在恢復大的資料集的時候,RDB方式會更快一些
  • 缺點:伺服器宕機,會丟失上一次RDB快照之後的持久化資料

AOF優缺點:

  • 優點:與RDB相比較,AOF通過append來追加檔案,速度要比RDB快,同時對伺服器效能消耗小,如果發生伺服器宕機,丟失的資料也只是一秒的資料
  • 缺點:AOF的檔案體積要大於RDB檔案的體積,redis重啟的恢復速度要比RDB慢

混合持久化

對於兩種持有的化方式來說,從兩者的優缺點來看,存在一定的互補性,一般推薦兩種持久化的方式同時使用,使用兩種同時持久化的方式只要修改redis.conf檔案中的配置即可

aof-use-rdb-preamble yes

持久化方案的建議

如果Redis只是用來做快取伺服器,比如資料庫查詢資料後快取,那可以不用考慮持久化,因為快取服務失效還能再從資料庫獲取恢復。

如果你要想提供很高的資料保障性,那麼建議你同時使用兩種持久化方式。如果你可以接受災難帶來的幾分鐘的資料丟失,那麼可以僅使用RDB。

通常的設計思路是利用主從複製機制來彌補持久化時效能上的影響。即Master上RDB、AOF都不做,保證Master的讀寫效能,而Slave上則同時開啟RDB和AOF(或4.0以上版本的混合持久化方式)來進行持久化,保證資料的安全性。

參考: