Redis系列四:redis持久化

redis支持RDB和AOF兩種持久化機制,持久化能夠避免因進程退出而形成數據丟失。redis

兩種持久化能夠單獨使用其中一種,但更多狀況下是將兩者結合使用。

1、RDB持久化

RDB持久化把當前進程數據生成快照(.rdb)文件保存到硬盤的過程,有手動觸發和自動觸發。數據庫

redis會在如下幾種狀況下對數據進行快照。
a)根據配置規則進行自動快照;
b)用戶執行save或bgsave命令;
c)執行flushall命令;
d)執行復制(replication)時;
 

一、根據配置規則進行自動快照

容許用戶自定義快照條件,當符合快照條件時,redis會自動執行快照操做。進行快照的題哦啊鍵能夠由用戶在配置文件中自定義,由兩個參數構成:時間窗口M和改動的鍵的個數N。每當時間M內被更改的鍵的個數大於N時,即符合自動快照條件。
如redis安裝目錄中包含的樣例配置文件中預置的3個條件:
save 900 1
save 300 10
save 60 10000
每條快照條件佔一行,而且以save參數開頭,同時能夠存在多個條件,條件之間是「或」的關係。上例中,save 900 1的意思是在15分鐘(900秒)內有一個或一個以上的鍵被更改則進行快照,同理,save 300 10表示子啊300秒內至少有10鍵被修改進行快照。


二、手動觸發有save和bgsave兩命令 

除redis自動進行快照外,服務重啓、手動遷移以及備份時咱們也會須要手動執行快照操做。redis提供兩個命令來完成這一操做。


save命令:阻塞當前Redis,直到RDB持久化過程完成爲止,若內存實例比較大會形成長時間阻塞,線上環境不建議用它
bgsave命令:redis進程執行fork操做建立子線程,由子線程完成持久化,阻塞時間很短(微秒級),是save的優化,在執行redis-cli shutdown關閉redis服務時,若是沒有開啓AOF持久化,自動執行bgsave;
顯然bgsave是對save的優化。緩存

bgsave運行流程安全

 

三、執行flushall命令

執行flushall命令時,redis會清除數據庫中全部的數據,要注意,不論清空數據庫的過程是否觸發了自動快照條件,只要自動快照條件不爲空,redis就會執行一次快照操做。
如當定義的快照條件爲當1秒內修改10000個鍵時進行自動快照,而當數據庫裏只有一個鍵時,執行flushall命令也會觸發快照,即便這一過程實際上只有一個鍵被修改了。
當沒有定義自動快照條件時,執行flushall則不會進行快照。

 四、執行復制(replication)時

當設置了主從模式時,redis會在複製初始化時進行自動快照。

五、快照原理

redis默認會將快照文件存儲在redis當前進程的工做目錄中的dump.rdb文件中,能夠經過配置dir和dbfilename兩個參數分別指定快照文件的存儲路徑和文件名。快照過程以下:
a、redis使用fork函數複製一份當前進程(父進程)的副本(子進程);
b、父進程繼續接收並處理客戶端發來的命令,而子進程開始將內存中的數據寫入硬盤中的臨時文件;
c、當子進程寫入完全部數據後會用到該臨時文件替換舊的rdb文件,至此一次快照操做完成。
 
注意:
在執行fork的時候操做系統會使用寫時複製(copy-on-write)策略,即fork函數發生的一刻父子進程共享同一內存數據,當父進程要更改其中某片數據時(如執行寫命令),操做系統會將該片數據複製一份以保證子進程的數據不受影響,因此新的rdb文件存儲的時執行fork一刻的內存數據。
寫時複製策略也保證了在fork的時刻雖然看上去生成了兩分內存副本,但實際上內存的佔用量並不會增長一倍。
當進行快照的過程當中,若寫入操做較多,形成fork先後數據差別較大,是會使得內存使用量顯著超過實際數據大小的,由於內存中不只保存了當前的數據庫數據,並且還保存着fork時刻的內存數據。進行內存用量估算很容易忽略該問題,形成內存用量超限。
 
經過上述發現redis在進行快照的過程當中不會修改rdb文件,只有快照結束後纔會將舊的文件替換成新的,也就是手任什麼時候候rdb文件都是完整的,使得咱們能夠經過定時備份rdb文件來實現redis數據庫備份。rdb文件是通過壓縮(能夠配置rdbccompression參數以禁用壓縮節省CPU佔用)的二進制格式,因此佔用的空間會小於內存中的數據大小,更加利於傳輸。
 
redis啓動後會讀取rdb快照文件,將數據從硬盤載入到內存,根據數量大小與結構和服務器性能不一樣,這個時間也不一樣,一般將一個記錄1000萬字符串類型鍵、大小爲1GB的快照文件載入內存中須要花費20~30秒。
經過rdb方式實現持久化,一旦redis異常退出,就會丟失最後一次快照之後更改的全部數據,這就須要經過組合設置自動快照條件的方式來將可能發生的數據損失控制在可以接受的範圍。
 

RDB文件的操做服務器

   命令:config set dir /usr/local  //設置rdb文件保存路徑app

   備份:bgsave  //將dump.rdb保存到usr/local下函數

   恢復:將dump.rdb放到redis安裝目錄與redis.conf同級目錄,重啓redis便可性能

   優勢:1,壓縮後的二進制文文件適用於備份、全量複製,用於災難恢復優化

              2,加載RDB恢復數據遠快於AOF方式spa

   缺點:1,沒法作到實時持久化,每次都要建立子進程,頻繁操做成本太高

              2,保存後的二進制文件,存在老版本不兼容新版本rdb文件的問題  

2、AOF持久化

針對RDB不適合實時持久化,redis提供了AOF持久化方式來解決。

開啓:redis.conf設置:appendonly yes  (默認不開啓,爲no)

默認文件名:appendfilename "appendonly.aof"   

一、流程說明

  • 全部的寫入命令(set hset)會append追加到aof_buf緩衝區中
  • AOF緩衝區向硬盤作sync同步
  • 隨着AOF文件愈來愈大,需按期對AOF文件rewrite重寫,達到壓縮
  • 當redis服務重啓,可load加載AOF文件進行恢復

AOF持久化流程:命令寫入(append),文件同步(sync),文件重寫(rewrite),重啓加載(load)

二、AOF配置詳解

appendonly yes     //啓用aof持久化方式

# appendfsync always //每收到寫命令就當即強制寫入磁盤,最慢的,可是保證徹底的持久化,不推薦使用

appendfsync everysec //每秒強制寫入磁盤一次,性能和持久化方面作了折中,推薦

# appendfsync no    //徹底依賴os,性能最好,持久化沒保證(操做系統自身的同步)

no-appendfsync-on-rewrite  yes  //正在導出rdb快照的過程當中,要不要中止同步aof

auto-aof-rewrite-percentage 100  //aof文件大小比起上次重寫時的大小,增加率100%時,重寫

auto-aof-rewrite-min-size 64mb   //aof文件,至少超過64M時,重寫

三、如何從AOF恢復?

  • 設置appendonly yes;
  • 將appendonly.aof放到dir參數指定的目錄;
  • 啓動Redis,Redis會自動加載appendonly.aof文件。

 

注意:
同步硬盤數據:
雖然每次執行更改數據庫內容的操做時,AOF都會將命令記錄在AOF文件中,可是事實上,因爲操做系統的緩存機制,數據並無真正地寫入硬盤,而是 進入了操做系統的硬盤緩存。在某人狀況下系統每30秒會執行一次同步操做,以便將硬盤緩存中的內容真正地寫入硬盤,在這30秒的過程當中若系統異常退出則會致使硬盤緩存中的數據丟失。爲了解決該問題須要redis在寫入AOF文件後主動要求系統將緩存內容同步到硬盤中。在redis中能夠經過appendfsync參數設置同步的時機:
#appendfsync always
appendfsync everysec
#appendfsync no
 
默認狀況採用everysec規則,即每秒執行一次同步操做,always表示每次執行寫入都會執行同步,這是最安全也是最慢的方式。no表示不主動進行同步操做,而是徹底交由操做系統來作(即每30秒一次),這個最快最不安全。通常everysec足夠了,既兼顧了性能又保證了安全。

3、redis重啓時恢復加載AOF與RDB順序及流程:

1,當AOF和RDB文件同時存在時,優先加載AOF

2,若關閉了AOF,加載RDB文件

3,加載AOF/RDB成功,redis重啓成功

4,AOF/RDB存在錯誤,redis啓動失敗並打印錯誤信息

相關文章
相關標籤/搜索