Redis持久化persistence

1、前言redis

因爲Redis的數據都存放在內存中,若是沒有配置持久化,redis重啓後數據就全丟失了,因而須要開啓redis的持久化功能,將數據保存到磁盤上,當redis重啓後,能夠從磁盤中恢復數據。數據庫

Redis提供兩種方式進行持久化,緩存

  • 一種是RDB()持久化(原理是將Reids在內存中的數據庫記錄定時dump到磁盤上的RDB持久化),安全

  • 另一種是AOF(append-only file)持久化(原理是將Reids的操做日誌以追加的方式寫入文件)。服務器

2、Redis 持久化app

Redis 提供了不一樣級別的持久化方式:工具

  • RDB持久化方式可以在指定的時間間隔能對你的數據進行快照存儲性能

  • AOF持久化方式記錄每次對服務器寫的操做,當服務器重啓的時候會從新執行這些命令來恢復原始的數據,AOF命令以redis協議追加保存每次寫的操做到文件末尾.Redis還能對AOF文件進行後臺重寫,使得AOF文件的體積不至於過大ui

  • 若是你只但願你的數據在服務器運行的時候存在,你也能夠不使用任何持久化方式.加密

  • 你也能夠同時開啓兩種持久化方式,     在這種狀況下, 當redis重啓的時候會優先載入AOF文件來恢復原始的數據,由於在一般狀況下AOF文件保存的數據集要比RDB文件保存的數據集要完整.

  • 最重要的事情是瞭解RDB和AOF持久化方式的不一樣,讓咱們以RDB持久化方式開始:

RDB的優勢

  • RDB是一個很是緊湊的文件,它保存了某個時間點的數據集,很是適用於數據集的備份,好比你能夠在每一個小時保存一下過去24小時內的數據,同時天天保存過去30天的數據,這樣即便出了問題你也能夠根據需求恢復到不一樣版本的數據集

  • 因爲RDB是一個緊湊的單一文件,很方便傳送到另外一個遠端數據中心或者Amazon S3(可能加密),很是適用於災難恢復

  • RDB在保存RDB文件時,父進程惟一須要作的就是fork出一個子進程,接下來的工做所有由子進程來作,父進程不須要再作其餘IO操做,因此RDB持久化方式能夠最大化redis的性能

  • 與AOF相比,在恢復大的數據集的時候,RDB方式會更快一些

RDB的缺點

  • 若是你但願在redis意外中止工做(例如電源中斷)的狀況下丟失的數據最少的話,那麼RDB不適合你。雖然你能夠配置不一樣的save時間點(例如每隔5分鐘而且對數據集有100個寫的操做),是Redis要完整的保存整個數據集是一個比較繁重的工做,你一般會每隔5分鐘或者更久作一次完整的保存,萬一在Redis意外宕機,你可能會丟失幾分鐘的數據.

  • RDB須要常常fork子進程來保存數據集到硬盤上,當數據集比較大的時候,fork的過程是很是耗時的,可能會致使Redis在一些毫秒級內不能響應客戶端的請求。若是數據集巨大而且CPU性能不是很好的狀況下,這種狀況會持續1秒,AOF也須要fork,可是你能夠調節重寫日誌文件的頻率來提升數據集的耐久度。

AOF 優勢

  • 使用AOF會讓你的Redis更加耐久,你可使用不一樣的fsync策略:無fsync,每秒fsync,每次寫的時候fsync。使用默認的每秒fsync策略,Redis的性能依然很好(fsync是由後臺線程進行處理的,主線程會盡力處理客戶端請求),一旦出現故障,你最多丟失1秒的數據。

  • AOF文件是一個只進行追加的日誌文件,因此不須要寫入seek,即便因爲某些緣由(磁盤空間已滿,寫的過程當中宕機等等)未執行完整的寫入命令,你也也可以使用redis-check-aof工具修復這些問題。

  • Redis能夠在AOF文件體積變得過大時,自動地在後臺對AOF進行重寫:     重寫後的新AOF文件包含了恢復當前數據集所需的最小命令集合。整個重寫操做是絕對安全的,由於Redis在建立新AOF文件的過程當中,會繼續將命令追加到現有的AOF文件裏面,即便重寫過程當中發生停機,現有的AOF文件也不會丟失。而一旦新AOF文件建立完畢,Redis就會從舊AOF文件切換到新AOF文件,並開始對新AOF文件進行追加操做。

  • AOF文件有序地保存了對數據庫執行的全部寫入操做,這些寫入操做以Redis協議的格式保存,所以AOF文件的內容很是容易被人讀懂,對文件進行分析(parse)也很輕鬆。導出(export)AOF 文件也很是簡單: 舉個例子, 若是你不當心執行了 FLUSHALL 命令, 但只要 AOF 文件未被重寫,那麼只要中止服務器,移除AOF文件末尾的FLUSHALL命令並重啓Redis ,就能夠將數據集恢復到FLUSHALL執行以前的狀態。

AOF 缺點

  • 對於相同的數據集來講,AOF文件的體積一般要大於RDB文件的體積。

  • 根據所使用的fsync策略,AOF的速度可能會慢於RDB。    

    在通常狀況下,每秒fsync的性能依然很是高而關閉fsync可讓AOF的速度和RDB同樣快,即便在高負荷之下也是如此。不過在處理巨大的寫入載入時,RDB能夠提供更有保證的最大延遲時間(latency)。

3、如何選擇使用哪一種持久化方式?

通常來講,若是想達到足以媲美PostgreSQL的數據安全性,你應該同時使用兩種持久化功能。

若是你很是關心你的數據,但仍然能夠承受數分鐘之內的數據丟失,那麼你能夠只使用RDB持久化。

有不少用戶都只使用AOF持久化,但咱們並不推薦這種方式: 由於定時生成 RDB 快照(snapshot)很是便於進行數據庫備份,而且RDB恢復數據集的速度也要比AOF恢復的速度要快,除此以外,使用RDB還能夠避免以前提到的AOF程序的bug。

Note: 由於以上提到的種種緣由,將來咱們可能會將AOF和RDB整合成單個持久化模型。

快照

在默認狀況下,Redis將數據庫快照保存在名字爲dump.rdb的二進制文件中。你能夠對Redis進行設置,讓它在「N秒內數據集至少有M個改動」這一條件被知足時,自動保存一次數據集。你也能夠經過調用SAVE或者BGSAVE,手動讓Redis進行數據集保存操做。

好比說,如下設置會讓Redis在知足「60秒內有至少有1000個鍵被改動」這一條件時,自動保存一次數據集:

save 60 1000

這種持久化方式被稱爲快照 snapshotting.

工做方式

當Redis須要保存dump.rdb文件時,服務器執行如下操做:

  • Redis調用fork(),同時擁有父進程和子進程。

  • 子進程將數據集寫入到一個臨時RDB文件中。

  • 當子進程完成對新RDB文件的寫入時,Redis用新RDB文件替換原來的RDB文件,並刪除舊的RDB文件。

這種工做方式使得Redis能夠從寫時複製(copy-on-write)機制中獲益。

只追加操做的文件(AOF)

快照功能並非很是耐久(durable): 若是Redis由於某些緣由而形成故障停機,那麼服務器將丟失最近寫入、且仍未保存到快照中的那些數據。 從1.1版本開始,Redis增長了一種徹底耐久的持久化方式:AOF持久化。

你能夠在配置文件中打開AOF方式:

appendonly yes

從如今開始,每當Redis執行一個改變數據集的命令時(好比 SET),這個命令就會被追加到AOF文件的末尾。這樣的話,當Redis從新啓時,程序就能夠經過從新執行AOF文件中的命令來達到重建數據集的目的。

日誌重寫

由於AOF的運做方式是不斷地將命令追加到文件的末尾,因此隨着寫入命令的不斷增長,AOF文件的體積也會變得愈來愈大。

舉個例子,若是你對一個計數器調用了100次INCR ,那麼僅僅是爲了保存這個計數器的當前值,AOF文件就須要使用100條記錄(entry)。然而在實際上,只使用一條SET命令已經足以保存計數器的當前值了,其他99條記錄實際上都是多餘的。

爲了處理這種狀況,Redis支持一種有趣的特性:能夠在不打斷服務客戶端的狀況下,對AOF文件進行重建(rebuild)。

執行BGREWRITEAOF命令,Redis將生成一個新的AOF文件,這個文件包含重建當前數據集所需的最少命令。

Redis 2.2須要本身手動執行 BGREWRITEAOF 命令;

Redis 2.4則能夠自動觸發AOF重寫,具體信息請查看2.4的示例配置文件。

AOF有多耐久性?

你能夠配置Redis多久纔將數據fsync到磁盤一次。有三種方式:

  • 每次有新命令追加到AOF文件時就執行一次fsync:很是慢,也很是安全。

  • 每秒fsync一次:足夠快(和使用RDB 持久化差很少),而且在故障時只會丟失1秒鐘的數據。

  • 從不fsync:將數據交給操做系統來處理。更快,也更不安全的選擇。

 

推薦(而且也是默認)的措施爲每秒fsync 一次, 這種fsync策略能夠兼顧速度和安全性。

4、若是AOF文件損壞了怎麼辦?

服務器可能在程序正在對AOF文件進行寫入時停機,若是停機形成了AOF文件出錯(corrupt), 那麼Redis在重啓時會拒絕載入這個AOF文件,從而確保數據的一致性不會被破壞。當發生這種狀況時,能夠用如下方法來修復出錯的AOF文件:

  • 爲現有的AOF文件建立一個備份。

  • 使用Redis附帶的redis-check-aof程序,對原來的AOF文件進行修復:$ redis-check-aof –fix

  • 使用diff -u對比修復後的AOF文件和原始AOF文件的備份,查看兩個文件之間的不一樣之處。(可選)

  • 重啓Redis服務器,等待服務器載入修復後的AOF文件,並進行數據恢復。

工做原理

AOF重寫和RDB建立快照同樣,都巧妙地利用了寫時複製機制:

  • Redis執行fork(),如今同時擁有父進程和子進程。

  • 子進程開始將新AOF文件的內容寫入到臨時文件。

  • 對於全部新執行的寫入命令,父進程一邊將它們累積到一個內存緩存中,一邊將這些改動追加到現有AOF文件的末尾,這樣即便在重寫的中途發生停機,現有的AOF文件也仍是安全的。

  • 當子進程完成重寫工做時,它給父進程發送一個信號,父進程在接收到信號以後,將內存緩存中的全部數據追加到新AOF文件的末尾。

  • 如今Redis原子地用新文件替換舊文件,以後全部命令都會直接追加到新AOF文件的末尾。

5、怎樣從RDB方式切換爲AOF方式

在Redis 2.2或以上版本,能夠在不重啓的狀況下,從RDB切換到 AOF :

  • 爲最新的dump.rdb文件建立一個備份。

  • 將備份放到一個安全的地方。

  • 執行如下兩條命令:

           redis-cli     config set appendonly yes

           redis-cli     config set save 「」

  • 確保寫命令會被正確地追加到AOF文件的末尾。

  • 執行的第一條命令開啓了AOF功能: Redis會阻塞直到初始AOF文件建立完成爲止,以後Redis會繼續處理命令請求,並開始將寫入命令追加到AOF文件末尾。

  • 執行的第二條命令用於關閉RDB功能。這一步是可選的,若是你願意的話,也能夠同時使用RDB和AOF這兩種持久化功能。

     

重要:別忘了在 redis.conf 中打開AOF功能! 不然的話服務器重啓以後,以前經過CONFIG SET設置的配置就會被遺忘,程序會按原來的配置來啓動服務器。

6、AOF和RDB之間的相互做用

在2.4及以上版本的Redis中,BGSAVE執行的過程當中,不能夠執行BGREWRITEAOF。 反過來講,在BGREWRITEAOF執行的過程當中,也不能夠執行 BGSAVE。這能夠防止兩個Redis後臺進程同時對磁盤進行大量的I/O操做。

若是BGSAVE正在執行,而且用戶顯示地調用BGREWRITEAO 命令,那麼服務器將向用戶回覆一個OK狀態,並告知用戶,BGREWRITEAOF已經被預約執行: 一旦BGSAVE執行完畢,BGREWRITEAOF就會正式開始。

當Redis啓動時,若是RDB持久化和AOF持久化都被打開了,那麼程序會優先使用AOF文件來恢復數據集,由於AOF文件所保存的數據一般是最完整的。

7、備份redis數據

請牢記下面這句話:確保你的數據由完整的備份。磁盤故障、節點失效諸如此類的問題均可能讓你的數據消失不見,不進行備份是很是危險的。

 

Redis對於數據備份是很是友好的,由於你能夠在服務器運行的時候對RDB文件進行復制: RDB文件一旦被建立,就不會進行任何修改。當服務器要建立一個新的RDB文件時,它先將文件的內容保存在一個臨時文件裏面,當臨時文件寫入完畢時,程序才使用 rename(2) 原子地用臨時文件替換原來的RDB文件。

這也就是說,不管什麼時候,複製RDB文件都是絕對安全的。

  • 建立一個按期任務(cron job), 每小時將一個RDB文件備份到一個文件夾,而且天天將一個RDB文件備份到另外一個文件夾。

  • 確保快照的備份都帶有相應的日期和時間信息,每次執行按期任務腳本時,使用find命令來刪除過時的快照。好比說, 你能夠保留最近48 小時內的每小時快照,還能夠保留最近一兩個月的每日快照。

  • 至少天天一次,將RDB備份到你的數據中心以外,或者至少是備份到你運行Redis服務器的物理機器以外。

8、經常使用配置

一、RDB持久化配置

Redis會將數據集的快照dump到dump.rdb文件中。此外,咱們也能夠經過配置文件來修改Redis服務器dump快照的頻率,在打開6379.conf文件以後,咱們搜索save,能夠看到下面的配置持久化策略:

  • save 900 1        #在900秒(15分鐘)以後,若是至少有1個key發生變化,則dump內存快照。

  •  save 300 10      #在300秒(5分鐘)以後,若是至少有10個key發生變化,則dump內存快照。

  •  save 60 10000  #在60秒(1分鐘)以後,若是至少有10000個key發生變化,則dump內存快照。

二、AOF持久化配置 

在Redis的配置文件中存在三種同步方式,它們分別是:

  • appendfsync always     #每次有數據修改發生時都會寫入AOF文件。

  • appendfsync everysec  #每秒鐘同步一次,該策略爲AOF的缺省策略。

  • appendfsync no            #從不一樣步。高效可是數據不會被持久化。

 

總結

RDB持久化是指在指定的時間間隔內將內存中的數據集快照寫入磁盤,實際操做過程是fork一個子進程,先將數據集寫入臨時文件,寫入成功後,再替換以前的文件,用二進制壓縮存儲。

 AOF持久化以日誌的形式記錄服務器所處理的每個寫、刪除操做,查詢操做不會記錄,以文本的方式記錄,能夠打開文件看到詳細的操做記錄。

 

參考

Redis https://redis.io/topics/persistence

 

--EOF--

相關文章
相關標籤/搜索