Redis 提供了不同級別的持久化方式:
- RDB持久化方式:能夠在指定的時間間隔能對你的數(shù)據(jù)進行快照存儲.
- AOF持久化方式:記錄每次對服務器寫的操作,當服務器重啟的時候會重新執(zhí)行這些命令來恢復原始的數(shù)據(jù),AOF命令以redis協(xié)議追加保存每次寫的操作到文件末尾.Redis還能對AOF文件進行后臺重寫,使得AOF文件的體積不至于過大。
如果你只希望你的數(shù)據(jù)在服務器運行的時候存在,你也可以不使用任何持久化方式.也可以同時開啟兩種持久化方式, 在這種情況下, 當redis重啟的時候會優(yōu)先載入AOF文件來恢復原始的數(shù)據(jù),因為在通常情況下AOF文件保存的數(shù)據(jù)集要比RDB(最少宕機前的1分鐘內(nèi)的數(shù)據(jù)丟失)文件保存的數(shù)據(jù)集要完整型诚。解下來說說兩種持久化方式各自的優(yōu)缺點霸妹。
RDB持久化方式
在默認情況下筹裕, Redis 將數(shù)據(jù)庫快照保存在名字為 dump.rdb的二進制文件中立倍。你可以對 Redis 進行設置舍哄, 讓它在“ N 秒內(nèi)數(shù)據(jù)集至少有 M 個改動”這一條件被滿足時溪椎, 自動保存一次數(shù)據(jù)集普舆。你也可以通過調(diào)用 SAVE或者 BGSAVE , 手動讓 Redis 進行數(shù)據(jù)集保存操作校读。
工作方式
當 Redis 需要保存 dump.rdb 文件時沼侣, 服務器執(zhí)行以下操作:
- Redis 調(diào)用forks. 同時擁有父進程和子進程。
- 子進程將數(shù)據(jù)集寫入到一個臨時 RDB 文件中歉秫。
- 當子進程完成對新 RDB 文件的寫入時蛾洛,Redis 用新 RDB 文件替換原來的 RDB 文件,并刪除舊的 RDB 文件。
1.RDB的 優(yōu)點
RDB是一個非常緊湊的文件,它保存了某個時間點得數(shù)據(jù)集,非常適用于數(shù)據(jù)集的備份,比如你可以在每個小時報保存一下過去24小時內(nèi)的數(shù)據(jù),同時每天保存過去30天的數(shù)據(jù),這樣即使出了問題你也可以根據(jù)需求恢復到不同版本的數(shù)據(jù)集轧膘。RDB是一個緊湊的單一文件,很方便傳送到另一個遠端數(shù)據(jù)中心钞螟,非常適用于災難恢復.RDB在保存RDB文件時父進程唯一需要做的就是fork出一個子進程,接下來的工作全部由子進程來做,父進程不需要再做其他IO操作谎碍,所以RDB持久化方式可以最大化redis的性能鳞滨。與AOF相比,在恢復大的數(shù)據(jù)集的時候,RDB方式會更快一些
2.RDB的缺點
如果希望在redis意外停止工作(例如電源中斷)的情況下丟失的數(shù)據(jù)最少的話蟆淀,那么RDB不適合你.雖然你可以配置不同的保存時間點(例如每隔5分鐘并且對數(shù)據(jù)集有100個寫的操作的時候進行保存),Redis要完整的保存整個數(shù)據(jù)集是一個比較繁重的工作,你通常會每隔5分鐘或者更久做一次完整的保存,萬一在Redis意外宕機,你可能會丟失幾分鐘的數(shù)據(jù).
RDB 需要經(jīng)常fork子進程來保存數(shù)據(jù)集到硬盤上,當數(shù)據(jù)集比較大的時候,fork的過程是非常耗時的,可能會導致Redis在一些毫秒級內(nèi)不能響應客戶端的請求.如果數(shù)據(jù)集巨大并且CPU性能不是很好的情況下,這種情況會持續(xù)1秒,AOF也需要fork,但是你可以調(diào)節(jié)重寫日志文件的頻率來提高數(shù)據(jù)集的耐久度.
AOF持久化方式
RDB快照功能并不是非常耐久(dura ble): 如果 Redis 因為某些原因而造成故障停機拯啦, 那么服務器將丟失最近寫入、且仍未保存到快照中的那些數(shù)據(jù)熔任。 從 1.1 版本開始褒链, Redis 增加了一種完全耐久的持久化方式: AOF 持久化。
你可以在配置文件中打開AOF方式:
appendonly yes
每當 Redis 執(zhí)行一個改變數(shù)據(jù)集的命令時(比如 SET)疑苔, 這個命令就會被追加到 AOF 文件的末尾甫匹。這樣的話, 當 Redis 重新啟時惦费, 程序就可以通過重新執(zhí)行 AOF 文件中的命令來達到重建數(shù)據(jù)集的目的兵迅。
日志重寫
因為 AOF 的運作方式是不斷地將命令追加到文件的末尾, 所以隨著寫入命令的不斷增加趁餐, AOF 文件的體積也會變得越來越大喷兼。舉個例子, 如果你對一個計數(shù)器調(diào)用了 100 次 INCR 后雷, 那么僅僅是為了保存這個計數(shù)器的當前值季惯, AOF 文件就需要使用 100 條記錄(entry)。然而在實際上臀突, 只使用一條 SET 命令已經(jīng)足以保存計數(shù)器的當前值了勉抓, 其余 99 條記錄實際上都是多余的。
如果AOF文件損壞了怎么辦候学?
服務器可能在程序正在對 AOF 文件進行寫入時停機藕筋, 如果停機造成了 AOF 文件出錯(corrupt), 那么 Redis 在重啟時會拒絕載入這個 AOF 文件梳码, 從而確保數(shù)據(jù)的一致性不會被破壞隐圾。當發(fā)生這種情況時, 可以用以下方法來修復出錯的 AOF 文件:
為現(xiàn)有的 AOF 文件創(chuàng)建一個備份掰茶。
使用 Redis 附帶的 redis-check-aof 程序暇藏,對原來的 AOF 文件進行修復:
$ redis-check-aof –fix
(可選)使用 diff -u 對比修復后的 AOF 文件和原始 AOF 文件的備份,查看兩個文件之間的不同之處濒蒋。
重啟 Redis 服務器盐碱,等待服務器載入修復后的 AOF 文件把兔,并進行數(shù)據(jù)恢復
為了處理這種情況, Redis 支持一種有趣的特性: 可以在不打斷服務客戶端的情況下瓮顽, 對 AOF 文件進行重建(rebuild)县好。執(zhí)行 BGREWRITEAOF 命令, Redis 將生成一個新的 AOF 文件暖混, 這個文件包含重建當前數(shù)據(jù)集所需的最少命令缕贡。Redis 2.2 需要自己手動執(zhí)行 BGREWRITEAOF 命令; Redis 2.4 則可以自動觸發(fā) AOF 重寫拣播, 具體信息請查看 2.4 的示例配置文件善绎。
AOF的優(yōu)點
使用AOF 會讓你的Redis更加耐久: 你可以使用不同的fsync策略:無fsync,每秒fsync,每次寫的時候fsync.使用默認的每秒fsync策略,Redis的性能依然很好(fsync是由后臺線程進行處理的,主線程會盡力處理客戶端請求),一旦出現(xiàn)故障,你最多丟失1秒的數(shù)據(jù).
AOF文件是一個只進行追加的日志文件,所以不需要寫入seek,即使由于某些原因(磁盤空間已滿诫尽,寫的過程中宕機等等)未執(zhí)行完整的寫入命令,你也也可使用redis-check-aof工具修復這些問題.
Redis 可以在 AOF 文件體積變得過大時,自動地在后臺對 AOF 進行重寫: 重寫后的新 AOF 文件包含了恢復當前數(shù)據(jù)集所需的最小命令集合炬守。 整個重寫操作是絕對安全的牧嫉,因為 Redis 在創(chuàng)建新 AOF 文件的過程中,會繼續(xù)將命令追加到現(xiàn)有的 AOF 文件里面减途,即使重寫過程中發(fā)生停機酣藻,現(xiàn)有的 AOF 文件也不會丟失。 而一旦新 AOF 文件創(chuàng)建完畢鳍置,Redis 就會從舊 AOF 文件切換到新 AOF 文件辽剧,并開始對新 AOF 文件進行追加操作。
AOF 文件有序地保存了對數(shù)據(jù)庫執(zhí)行的所有寫入操作税产, 這些寫入操作以 Redis 協(xié)議的格式保存怕轿, 因此 AOF 文件的內(nèi)容非常容易被人讀懂, 對文件進行分析(parse)也很輕松辟拷。 導出(export) AOF 文件也非常簡單: 舉個例子撞羽, 如果你不小心執(zhí)行了 FLUSHALL 命令, 但只要 AOF 文件未被重寫衫冻, 那么只要停止服務器诀紊, 移除 AOF 文件末尾的 FLUSHALL 命令, 并重啟 Redis 隅俘, 就可以將數(shù)據(jù)集恢復到 FLUSHALL 執(zhí)行之前的狀態(tài)邻奠。
AOF的缺點
對于相同的數(shù)據(jù)集來說,AOF 文件的體積通常要大于 RDB 文件的體積
根據(jù)所使用的 fsync (同步內(nèi)存中所有已修改的文件數(shù)據(jù)到儲存設備)策略为居,AOF 的速度可能會慢于 RDB 碌宴。 在一般情況下, 每秒 fsync 的性能依然非常高颜骤, 而關閉 fsync 可以讓 AOF 的速度和 RDB 一樣快唧喉, 即使在高負荷之下也是如此。 不過在處理巨大的寫入載入時,RDB 可以提供更有保證的最大延遲時間(latency)八孝。
持久化方式的選擇
想要足夠的數(shù)據(jù)安全性董朝,應該同時選用兩種持久化方式。
如果你非常關心你的數(shù)據(jù)干跛, 但仍然可以承受數(shù)分鐘以內(nèi)的數(shù)據(jù)丟失子姜, 那么你可以只使用 RDB 持久化