Redis從入門到精通(4、Redis的持久化和數據備份與恢復)

本文將對Redis的兩種持久化方式作詳細的介紹,從配置,機制,優缺點幾方面講起,最後是關於數據的備份與恢復的介紹。

Redis持久化簡介

Redis提供了兩種持久化的選項,一種是快照文件(snapshotting,RDB),它會基於某個時間點將數據所有寫入硬盤中(默認爲dump.rdb)。另外一種是只追加文件(append-only,AOF),它會在執行寫入命令時將命令寫入到硬盤中。linux

Redis持久化數據最主要是爲了數據備份,故障恢復,也有一些通過耗時較長的計算結果存在Redis中,若是這些數據存在硬盤中,即便服務器重啓了以後,這些數據仍是存在的,不用再去耗時計算了。redis

這兩種方式能夠單獨使用,也能夠結合起來使用。最重要的仍是要理解RDB和AOF的優劣勢,結合本身的應用作一個權衡。服務器

RDB (SNAPSHOTTING)

RDB 配置項

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

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

  • dir ./,指定 RDBAOF 文件的路徑
  • save 900 1 , 多久執行一次快照操做, 900秒內有1次寫入則執行快照操做
  • stop-writes-on-bgsave-error , 建立快照失敗後是否依然寫命令,默認爲yes
  • rdbcompression , 是否對快照文件進行壓縮,默認爲 yes
  • rdbchecksum , rdb文件是否啓用CRC64文件數據完整性檢查,5.0版本以後的屬性,默認爲 yes,開啓後在 saveload 時將耗費 10%的性能,能夠關閉此配置來提升性能
  • dbfilename , rdb文件名,默認爲 dump.rdb

RDB 詳解

Redis 經過建立快照的方式,得到內存中某個時間點的數據副本。Redis重啓時能夠從 RDB 文件上恢復數據。咱們也能夠把 RDB 文件備份在別的服務器上。工具

根據上述的幾個配置項,快照被寫入 dir 目錄下的 dbfilename 文件中。若是在新的快照文件建立完成以前,Redis服務器發生了宕機,那這期間的數據將丟失。性能

Redis中有兩個命令能夠建立快照文件, SAVEBGSAVEui

  • 執行 SAVE 命令後,服務器將不會再相應任何命令,直到快照文件完成。
  • 執行 BGSAVE 命令後,Redis父進程會調用 fork 來建立一個子進程,由子進程去負責快照文件的寫入,父進程則繼續處理客戶端的命令請求。
  1. 客戶端能夠直接向服務器發送 SAVE 或者 BGSAVE
  2. 若是設置了 save 配置項,達到配置項的要求時,Redis會自動執行 BGSAVE 命令。該配置項能夠設置多組,若是設置了多組,只要達到其中一組的要求,就會執行BGSAVE
  3. Redis經過SHUTDOWN 指令,或者接收到標準 TERM 信號時,會執行 SAVE 命令,阻塞全部客戶端,直到 SAVE 命令執行完成後,關閉服務器
  4. Redis配置了複製集以後,從服務器向主服務器發來 SYNC 命令,主服務器會執行 BGSAVE 命令,而後將快照文件發給從服務器

須要注意的是, 執行 BGSAVE 命令可能會形成服務器暫停幾毫秒或者幾秒,具體時長要根據數據量的大小以及服務器的配置來看。在數據量特別大,服務器內存吃緊的狀況下,可能會形成長時間的停頓,甚至宕機。一般狀況下, BGSAVE 是要比 SAVE 好一些,由於不會影響客戶端的請求,不過在數據量巨大的狀況下, BGSAVE 可能會比 SAVE 指令耗時更長。因此仍是要結合具體的數據狀況來選擇。若是能夠接受數據丟失5分鐘,15分鐘,1小時甚至更長時間的數據的話,甚至能夠關閉自動保存,由客戶端決定何時來執行快照副本的建立。this

RDB 優勢

  • 冷備份,例如:能夠設置每一個小時歸檔數據集,並備份至其餘服務器,發生災難時能夠選擇恢復數據集的不一樣副本。
  • 對 Redis 的讀寫影響小,最大限度的提升了性能。父進程會fork一個子進程區作數據集的歸檔,不會影響父進程的工做。
  • 在恢復數據集時,RDB比AOF更加高效

RDB 缺點

  • 在發生災難的時候,RDB會比AOF丟失的數據多。能夠經過設置來更改保存點,通常設置爲5分鐘。
  • RDB 每次在fork子線程來執行RDB快照文件時,若是數據文件特別大且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 ,在重寫時是否執行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 的說明atom

選項 同步頻率
always 每次執行寫入操做都執行fsync,這將很是影響性能,嚴重下降Redis的吞吐
everysec 每隔1s執行一次 fsync,顯示的將多個寫入命令同步到硬盤,性能很是好,若是丟失數據也只是丟失1s內的數據
no 不執行 fsync ,交給操做系統去處理。通常Linux是每隔30s刷新一次數據到磁盤上,取決於內核的精準調整

(2) 關於 rewrite操作系統

前面提到,AOF是將每條寫入命令都同步到硬盤,包括刪除key的指令,一直這麼下去,AOF文件將會變的很是龐大,甚至佔用全部硬盤空間。

rewrite 就是解決這個問題的,它對應的命令是 BGREWRITEAOF , 這個命令和 BGSAVE 很是類似,都是由Redis父進程fork的子進程去執行操做,因此它和 BGSAVE 有相同的缺點。
BGREWRITEAOF 會經過移除AOF中冗餘命令的方式來重寫AOF文件,重寫以後體積就會變小不少。

auto-aof-rewrite-percentageauto-aof-rewrite-min-size 這兩項配置是配置自動重寫AOF文件的觸發條件,只有在設置了 appendonly yes 的狀況下,也就是開啓了AOF持久化機制纔會生效。
舉個例子,auto-aof-rewrite-percentage 100, auto-aof-rewrite-min-size 64mb 表示,當AOF大於 64mb 而且比上一次重寫以後的體積大了100% 纔會執行BGREWRITEAOF。能夠經過修改這兩項參數來控制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重啓時發現了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日誌中的寫入指令來從新構建整個數據集。
Redis並不會將數據直接寫入硬盤中,而是會先將數據寫進linux os cache,而後在經過配置的appendfsync 設置的時間來執行fsync操做,強行將數據刷入磁盤文件。
AOF是存放每條的寫命令,因此會不斷擴大,當大到必定程度,AOF作rewrite操做,就會基於當時redis內存中的數據,來從新構造一個更小的AOF文件,而後將舊的文件刪掉。

AOF 優勢

  • AOF能夠更好的保護數據不丟失,通常AOF每隔一秒,經過後臺線程執行一次fsync,最多丟失1s的數據。能夠經過設置改成每次寫入數據時都執行fsync,不過這很是影響性能。
  • AOF日誌僅僅時附加日誌,若是由於某些緣由致使只寫入通常,也能夠經過redis-check-aof 輕鬆修復。
  • AOF日誌文件過大時,會在後臺執行rewrite操做,不會影響客戶端的讀寫
  • AOF日誌文件可能性好,由於記錄的時一條一條的指令。

AOF 缺點

  • AOF日誌一般比RDB數據快照文件更大
  • 作數據恢復的時候可能會比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兩種方式的優缺點有了大概的瞭解,具體如何選擇,還需根據本身的業務狀況來選擇,這裏給出的意見是兩種一塊兒用,條件容許的話,將持久化的文件時常備份到多臺不一樣的服務器上。

Redis4.0之後,支持AOF和RDB混合使用,在 redis.conf 中經過 aof-use-rdb-preamble yes 設置。


更多詳細內容參考:

Redis持久化官方文檔

Redis實戰

相關文章
相關標籤/搜索