Redis從入門到精通(四往产、Redis的持久化和數(shù)據(jù)備份與恢復)

Redis提供了兩種持久化的選項,一種是快照文件(snapshotting,RDB),它會基于某個時間點將數(shù)據(jù)全部寫入硬盤中(默認為dump.rdb)哟旗。另一種是只追加文件(append-only,AOF),它會在執(zhí)行寫入命令時將命令寫入到硬盤中碟联。

Redis持久化數(shù)據(jù)最主要是為了數(shù)據(jù)備份,故障恢復,也有一些經過耗時較長的計算結果存在Redis中,如果這些數(shù)據(jù)存在硬盤中,即使服務器重啟了之后,這些數(shù)據(jù)還是存在的,不用再去耗時計算了脑豹。

這兩種方式可以單獨使用,也可以結合起來使用抗愁。最重要的還是要理解RDB和AOF的優(yōu)劣勢馁蒂,結合自己的應用做一個權衡。

RDB (SNAPSHOTTING)

RDB 配置項

save 900 1
stop-writes-on-bgsave-error yes
rdbcompression yes
rdbchecksum yes
dbfilename dump.rdb
dir ./

上面6項配置中,前5項均是RDB的配置,最后一個是RDBAOF 公用的配置

  • dir ./,指定 RDBAOF 文件的路徑
  • save 900 1 , 多久執(zhí)行一次快照操作, 900秒內有1次寫入則執(zhí)行快照操作
  • stop-writes-on-bgsave-error , 創(chuàng)建快照失敗后是否依然寫命令,默認為yes
  • rdbcompression , 是否對快照文件進行壓縮,默認為 yes
  • rdbchecksum , rdb文件是否啟用CRC64文件數(shù)據(jù)完整性檢查,5.0版本之后的屬性,默認為 yes,開啟后在 saveload 時將耗費 10%的性能,可以關閉此配置來提高性能
  • dbfilename , rdb文件名,默認為 dump.rdb

RDB 詳解

Redis 通過創(chuàng)建快照的方式,獲得內存中某個時間點的數(shù)據(jù)副本蜘腌。Redis重啟時可以從 RDB 文件上恢復數(shù)據(jù)沫屡。我們也可以把 RDB 文件備份在別的服務器上。

根據(jù)上述的幾個配置項,快照被寫入 dir 目錄下的 dbfilename 文件中撮珠。如果在新的快照文件創(chuàng)建完成之前,Redis服務器發(fā)生了宕機,那這期間的數(shù)據(jù)將丟失沮脖。

Redis中有兩個命令可以創(chuàng)建快照文件, SAVEBGSAVE

  • 執(zhí)行 SAVE 命令后,服務器將不會再相應任何命令,直到快照文件完成。
  • 執(zhí)行 BGSAVE 命令后,Redis父進程會調用 fork 來創(chuàng)建一個子進程,由子進程去負責快照文件的寫入,父進程則繼續(xù)處理客戶端的命令請求勺届。
  1. 客戶端可以直接向服務器發(fā)送 SAVE 或者 BGSAVE
  2. 如果設置了 save 配置項,達到配置項的要求時,Redis會自動執(zhí)行 BGSAVE 命令驶俊。該配置項可以設置多組,如果設置了多組,只要達到其中一組的要求,就會執(zhí)行BGSAVE
  3. Redis通過SHUTDOWN 指令,或者接收到標準 TERM 信號時,會執(zhí)行 SAVE 命令,阻塞所有客戶端,直到 SAVE 命令執(zhí)行完成后,關閉服務器
  4. Redis配置了復制集之后,從服務器向主服務器發(fā)來 SYNC 命令,主服務器會執(zhí)行 BGSAVE 命令,然后將快照文件發(fā)給從服務器

需要注意的是, 執(zhí)行 BGSAVE 命令可能會造成服務器暫停幾毫秒或者幾秒,具體時長要根據(jù)數(shù)據(jù)量的大小以及服務器的配置來看。在數(shù)據(jù)量特別大,服務器內存吃緊的情況下,可能會造成長時間的停頓,甚至宕機免姿。通常情況下, BGSAVE 是要比 SAVE 好一些,因為不會影響客戶端的請求,不過在數(shù)據(jù)量巨大的情況下, BGSAVE 可能會比 SAVE 指令耗時更長饼酿。所以還是要結合具體的數(shù)據(jù)情況來選擇。如果可以接受數(shù)據(jù)丟失5分鐘,15分鐘,1小時甚至更長時間的數(shù)據(jù)的話,甚至可以關閉自動保存,由客戶端決定什么時候來執(zhí)行快照副本的創(chuàng)建胚膊。

RDB 優(yōu)點

  • 冷備份故俐,例如:可以設置每個小時歸檔數(shù)據(jù)集,并備份至其他服務器,發(fā)生災難時可以選擇恢復數(shù)據(jù)集的不同副本。
  • 對 Redis 的讀寫影響小,最大限度的提高了性能紊婉。父進程會fork一個子進程區(qū)做數(shù)據(jù)集的歸檔,不會影響父進程的工作药版。
  • 在恢復數(shù)據(jù)集時,RDB比AOF更加高效

RDB 缺點

  • 在發(fā)生災難的時候喻犁,RDB會比AOF丟失的數(shù)據(jù)多槽片。可以通過設置來更改保存點,一般設置為5分鐘肢础。
  • RDB 每次在fork子線程來執(zhí)行RDB快照文件時,如果數(shù)據(jù)文件特別大且CPU性能不佳,可能造成服務暫停幾毫秒或者幾秒筐乳。

AOF (append-only)

AOF 配置項

appendonly no
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes
  • appendonly,是否開啟 AOF,默認為 no
  • appendfilename, AOF 文件名
  • appendfsync ① ,多久才將寫入的內容同步到硬盤上,有 always,everysec(默認),no 三種。下面對比了三種方式的性能
  • no-appendfsync-on-rewrite ,在重寫時是否執(zhí)行fsync操作,默認為 no
  • auto-aof-rewrite-percentage ②, 當文件達到上一個文件的多少百分比時自動重寫
  • auto-aof-rewrite-min-size ②,自動重寫的最小文件體積
  • aof-load-truncated ③,AOF文件被截斷時是否啟動,默認為 yes
  • aof-use-rdb-preamble ④,是否支持AOF和RDB混合使用,默認為 yes

(1) 關于 appendfsync 的說明

選項 同步頻率
always 每次執(zhí)行寫入操作都執(zhí)行fsync,這將非常影響性能,嚴重降低Redis的吞吐
everysec 每隔1s執(zhí)行一次 fsync,顯示的將多個寫入命令同步到硬盤,性能非常好,如果丟失數(shù)據(jù)也只是丟失1s內的數(shù)據(jù)
no 不執(zhí)行 fsync ,交給操作系統(tǒng)去處理乔妈。一般Linux是每隔30s刷新一次數(shù)據(jù)到磁盤上,取決于內核的精準調整

(2) 關于 rewrite

前面提到,AOF是將每條寫入命令都同步到硬盤,包括刪除key的指令,一直這么下去,AOF文件將會變的非常龐大,甚至占用所有硬盤空間。

rewrite 就是解決這個問題的,它對應的命令是 BGREWRITEAOF , 這個命令和 BGSAVE 非常相似,都是由Redis父進程fork的子進程去執(zhí)行操作,所以它和 BGSAVE 有相同的缺點氓皱。
BGREWRITEAOF 會通過移除AOF中冗余命令的方式來重寫AOF文件,重寫之后體積就會變小很多路召。

auto-aof-rewrite-percentageauto-aof-rewrite-min-size 這兩項配置是配置自動重寫AOF文件的觸發(fā)條件,只有在設置了 appendonly yes 的情況下,也就是開啟了AOF持久化機制才會生效。
舉個例子,auto-aof-rewrite-percentage 100, auto-aof-rewrite-min-size 64mb 表示,當AOF大于 64mb 并且比上一次重寫之后的體積大了100% 才會執(zhí)行BGREWRITEAOF波材」傻可以通過修改這兩項參數(shù)來控制AOF重寫的頻率。

(3) 關于 aof-load-truncated

在寫入AOF文件的過程中,可能會由于各種原因(停電,磁盤空間占滿,服務器故障導致Redis宕機)導致AOF寫入命令被截斷,如果該配置項設置為 yes , Redis將會在重啟時,清除被截斷的命令之后的所有命令(通常情況下后面也沒有命令了),然后正常重啟廷区。如果不想這樣,可以將此項設置為 no ,Redis將會在重啟時拋出錯誤并退出唯灵。需要注意的是:最新版本中即使設置了 no , Redis也會將被截斷的命令之后所有命令刪除,以保證下次重新啟動時能夠正常啟動,老版本中則不會,需要使用 redis-check-aof 工具來修復,具體命令是redis-check-aof --fix

以下是aof-load-truncated yes的情況下,Redis重啟時發(fā)現(xiàn)了AOF被截斷,打出的日志

* Reading RDB preamble from AOF file...
* Reading the remaining AOF tail...
# !!! Warning: short read while loading the AOF file !!!
# !!! Truncating the AOF at offset 439 !!!
# AOF loaded anyway because aof-load-truncated is enabled

(4) 關于 aof-use-rdb-preamble

Redis4.0以后,支持AOF和RDB混合使用,可以通過此項進行配置是否開啟隙轻。

AOF 詳解

AOF機制對每條寫入命令作為日志埠帕,以append-only的模式寫入一個日志文件中,在redis重啟的時候玖绿,可以通過回放AOF日志中的寫入指令來重新構建整個數(shù)據(jù)集敛瓷。
Redis并不會將數(shù)據(jù)直接寫入硬盤中,而是會先將數(shù)據(jù)寫進linux os cache,然后在通過配置的appendfsync 設置的時間來執(zhí)行fsync操作,強行將數(shù)據(jù)刷入磁盤文件斑匪。
AOF是存放每條的寫命令,所以會不斷擴大,當大到一定程度,AOF做rewrite操作,就會基于當時redis內存中的數(shù)據(jù),來重新構造一個更小的AOF文件,然后將舊的文件刪掉呐籽。

AOF 優(yōu)點

  • AOF可以更好的保護數(shù)據(jù)不丟失,一般AOF每隔一秒,通過后臺線程執(zhí)行一次fsync,最多丟失1s的數(shù)據(jù)。可以通過設置改為每次寫入數(shù)據(jù)時都執(zhí)行fsync狡蝶,不過這非常影響性能庶橱。
  • AOF日志僅僅時附加日志,如果因為某些原因導致只寫入一般贪惹,也可以通過redis-check-aof 輕松修復苏章。
  • AOF日志文件過大時,會在后臺執(zhí)行rewrite操作,不會影響客戶端的讀寫
  • AOF日志文件可能性好,因為記錄的時一條一條的指令馍乙。

AOF 缺點

  • AOF日志通常比RDB數(shù)據(jù)快照文件更大
  • 做數(shù)據(jù)恢復的時候可能會比RDB慢
  • 做定期的冷備沒有RDB方便

RDB和AOF文件損壞了

Redis為我們提供了工具,redis-check-rdbredis-check-aof

具體使用方法如下:

[root@iZnom30el3gvhxZ ~]# redis-check-aof
Usage: redis-check-aof [--fix] <file.aof>
[root@iZnom30el3gvhxZ ~]# redis-check-rdb
Usage: redis-check-rdb <rdb-file-name>

下面是官方文檔中對于AOF文件損壞的一些說明布近,我摘了過來:

If the AOF file is not just truncated, but corrupted with invalid byte sequences in the middle, things are more complex. Redis will complain at startup and will abort:

* Reading the remaining AOF tail...
# Bad file format reading the append only file: make a backup of your AOF file, then use ./redis-check-aof --fix <filename>

The best thing to do is to run the redis-check-aof utility, initially without the --fix option, then understand the problem, jump at the given offset in the file, and see if it is possible to manually repair the file: the AOF uses the same format of the Redis protocol and is quite simple to fix manually. Otherwise it is possible to let the utility fix the file for us, but in that case all the AOF portion from the invalid part to the end of the file may be discareded, leading to a massive amount of data lost if the corruption happen to be in the initial part of the file.

How it works

Log rewriting uses the same copy-on-write trick already in use for snapshotting. This is how it works:

  • Redis forks, so now we have a child and a parent process.
  • The child starts writing the new AOF in a temporary file.
  • The parent accumulates all the new changes in an in-memory buffer (but at the same time it writes the new changes in the old append-only file, so if the rewriting fails, we are safe).
  • When the child is done rewriting the file, the parent gets a signal, and appends the in-memory buffer at the end of the file generated by the child.
  • Profit! Now Redis atomically renames the old file into the new one, and starts appending new data into the new file.

How I can switch to AOF, if I'm currently using dump.rdb snapshots?

There is a different procedure to do this in Redis 2.0 and Redis 2.2, as you can guess it's simpler in Redis 2.2 and does not require a restart at all.

Redis >= 2.2

  • Make a backup of your latest dump.rdb file.
  • Transfer this backup into a safe place.
  • Issue the following two commands:
  • redis-cli config set appendonly yes
  • redis-cli config set save ""
  • Make sure that your database contains the same number of keys it contained.
  • Make sure that writes are appended to the append only file correctly.

The first CONFIG command enables the Append Only File. In order to do so Redis will block to generate the initial dump, then will open the file for writing, and will start appending all the next write queries.

The second CONFIG command is used to turn off snapshotting persistence. This is optional, if you wish you can take both the persistence methods enabled.

IMPORTANT: remember to edit your redis.conf to turn on the AOF, otherwise when you restart the server the configuration changes will be lost and the server will start again with the old configuration.

Redis 2.0

  • Make a backup of your latest dump.rdb file.
  • Transfer this backup into a safe place.
  • Stop all the writes against the database!
  • Issue a redis-cli bgrewriteaof. This will create the append only file.
  • Stop the server when Redis finished generating the AOF dump.
  • Edit redis.conf end enable append only file persistence.
  • Restart the server.
  • Make sure that your database contains the same number of keys it contained.
  • Make sure that writes are appended to the append only file correctly.

RDB和AOF如何選擇?

通過以上內容,應該已經對RDB和AOF兩種方式的優(yōu)缺點有了大概的了解,具體如何選擇,還需根據(jù)自己的業(yè)務情況來選擇,這里給出的意見是兩種一起用,條件允許的話,將持久化的文件時常備份到多臺不同的服務器上。

Redis4.0以后丝格,支持AOF和RDB混合使用,在 redis.conf 中通過 aof-use-rdb-preamble yes 設置撑瞧。

其他

以下是Redis官方文檔中關于 數(shù)據(jù)備份災難恢復 的說明,我做了一下翻譯,官方給出的方案已經很完善了,可以參考以下,結合自己的實際情況實施

數(shù)據(jù)備份

在開始本節(jié)之前,確保讀了以下句子:對你的數(shù)據(jù)庫做備份。磁盤損壞,云實例消失等等:沒有備份意味著將數(shù)據(jù)丟失到 /dev/null

Redis對于數(shù)據(jù)備份非常友好,因為你可以在數(shù)據(jù)庫運行時拷貝RDB文件: RDB文件一旦生成就不會改變,它在生成時使用一個臨時的名字,當新的快照文件完成之后會以原子的方式 rename 確保替換掉舊的快照文件显蝌。

這意味著當數(shù)據(jù)庫正在運行時拷貝RDB文件是安全的预伺。下面是我們的建議:

  • 在服務器中創(chuàng)建一個 cron 作業(yè),在一個文件夾中每隔一個小時創(chuàng)建一次快照的副本,在另一個文件夾中每隔一天創(chuàng)建一次快照的副本。
  • 每次運行 cron 作業(yè)的腳本時,確保調用一次 find 命令來確保刪除太舊的快照副本: 例如,你可以保留最近48小時的每小時快照副本和一兩個月內的每日快照副本曼尊。確保使用數(shù)據(jù)和時間信息命名快照副本酬诀。
  • 每天至少一次把這些RDB快照備份到 數(shù)據(jù)中心之外 或者 至少是運行著Redis實例的物理機之外。

如果Redis只開啟了AOF的持久化模式,也仍然可以創(chuàng)建AOF文件的備份骆撇。該文件可能缺少最后部分,但是Redis仍然可以加載它(參考AOF文件被截斷相關內容)瞒御。

災難恢復

Redis的災難恢復和備份基本相同,而且可以傳輸?shù)皆S多不同的數(shù)據(jù)中心。以這種方式保護數(shù)據(jù),即使在正運行著Redis的實例的主數(shù)據(jù)中心發(fā)生了災難性事件,這些備份的數(shù)據(jù)也很安全神郊。

由于許多Redis用戶正處于起始階段,可能沒有足夠的資金去執(zhí)行上述方案肴裙。我們將介紹最有趣的災難恢復方案,這些技術成本不會很高。

  • 亞馬遜S3和其他云是實現(xiàn)你的災難恢復系統(tǒng)的一個好方案涌乳。用加密的方式把你的每日和每小時的數(shù)據(jù)快照傳輸?shù)絊3蜻懦。你可以用gpg -c(對稱加密)加密你的數(shù)據(jù)。保證把你的密碼保存在其他安全的地方(比如給你的組織中最重要的人一個副本)夕晓。推薦你使用多個數(shù)據(jù)存儲服務來提升你的數(shù)據(jù)安全性宛乃。
  • 用SCP(SSH的一部分)將你的快照傳到其他遠程服務器。這是一個相當簡單和安全的方式: 在離你很遠的地方獲取一個VPS,在那里安裝SSH,并生成一個沒有密碼的ssh客戶端,然后把它添加到VPS的 authorized_keys 文件中蒸辆。你已經準備好了以自動的方式傳輸這些備份文件征炼。至少從兩個不同的VPS提供商獲取VPS,以保證最好的結果。

最重要的是理解,如果你沒有以正確的方式去實現(xiàn)上述方案躬贡。至少絕對確保在傳輸完成之后檢查文件的大小(它應該要和你復制的文件大小一致),如果你使用VPS的話,還要驗證SHA1摘要柒室。

如果備份在傳輸過程中由于某些原因失敗了,你也需要一套獨立的警報系統(tǒng)。


更多詳細內容參考:

Redis持久化官方文檔

Redis實戰(zhàn)

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末逗宜,一起剝皮案震驚了整個濱河市雄右,隨后出現(xiàn)的幾起案子空骚,更是在濱河造成了極大的恐慌,老刑警劉巖擂仍,帶你破解...
    沈念sama閱讀 217,542評論 6 504
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件囤屹,死亡現(xiàn)場離奇詭異,居然都是意外死亡逢渔,警方通過查閱死者的電腦和手機肋坚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,822評論 3 394
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來肃廓,“玉大人智厌,你說我怎么就攤上這事∶ど蓿” “怎么了铣鹏?”我有些...
    開封第一講書人閱讀 163,912評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長哀蘑。 經常有香客問我诚卸,道長,這世上最難降的妖魔是什么绘迁? 我笑而不...
    開封第一講書人閱讀 58,449評論 1 293
  • 正文 為了忘掉前任合溺,我火速辦了婚禮,結果婚禮上缀台,老公的妹妹穿的比我還像新娘棠赛。我一直安慰自己,他們只是感情好膛腐,可當我...
    茶點故事閱讀 67,500評論 6 392
  • 文/花漫 我一把揭開白布睛约。 她就那樣靜靜地躺著,像睡著了一般依疼。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上而芥,一...
    開封第一講書人閱讀 51,370評論 1 302
  • 那天律罢,我揣著相機與錄音,去河邊找鬼棍丐。 笑死误辑,一個胖子當著我的面吹牛,可吹牛的內容都是我干的歌逢。 我是一名探鬼主播巾钉,決...
    沈念sama閱讀 40,193評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼秘案!你這毒婦竟也來了砰苍?” 一聲冷哼從身側響起潦匈,我...
    開封第一講書人閱讀 39,074評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎赚导,沒想到半個月后茬缩,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經...
    沈念sama閱讀 45,505評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡吼旧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,722評論 3 335
  • 正文 我和宋清朗相戀三年凰锡,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片圈暗。...
    茶點故事閱讀 39,841評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡掂为,死狀恐怖,靈堂內的尸體忽然破棺而出员串,到底是詐尸還是另有隱情勇哗,我是刑警寧澤,帶...
    沈念sama閱讀 35,569評論 5 345
  • 正文 年R本政府宣布昵济,位于F島的核電站智绸,受9級特大地震影響,放射性物質發(fā)生泄漏访忿。R本人自食惡果不足惜瞧栗,卻給世界環(huán)境...
    茶點故事閱讀 41,168評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望海铆。 院中可真熱鬧迹恐,春花似錦、人聲如沸卧斟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,783評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽珍语。三九已至锤岸,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間板乙,已是汗流浹背是偷。 一陣腳步聲響...
    開封第一講書人閱讀 32,918評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留募逞,地道東北人蛋铆。 一個月前我還...
    沈念sama閱讀 47,962評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像放接,于是被迫代替她去往敵國和親刺啦。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,781評論 2 354