Redis(二)、數據的持久化

Redis數據持久化html

第1章 Redis持久化

Redis 提供了多種不一樣級別的持久化方式:redis

q  RDB 持久化能夠在指定的時間間隔內生成數據集的時間點快照(point-in-time snapshot)。數據庫

q  AOF 持久化記錄服務器執行的全部寫操做命令,並在服務器啓動時,經過從新執行這些命令來還原數據集。 AOF 文件中的命令所有以 Redis 協議的格式來保存,新命令會被追加到文件的末尾。 Redis 還能夠在後臺對 AOF 文件進行重寫(rewrite),使得 AOF 文件的體積不會超出保存數據集狀態所需的實際大小。緩存

q  Redis 還能夠同時使用 AOF 持久化和 RDB 持久化。 在這種狀況下, Redis 重啓時, 它會優先使用 AOF 文件來還原數據集, 由於 AOF 文件保存的數據集一般比 RDB 文件所保存的數據集更完整。安全

q  你甚至能夠關閉持久化功能,讓數據只在服務器運行時存在。bash

第2章 RD--快照

2.1 RDB的優勢

q  RDB 是一個很是緊湊(compact)的文件,它保存了 Redis 在某個時間點上的數據集。 這種文件很是適合用於進行備份: 好比說,你能夠在最近的 24 小時內,每小時備份一次 RDB 文件,而且在每月的每一天,也備份一個 RDB 文件。 這樣的話,即便趕上問題,也能夠隨時將數據集還原到不一樣的版本。服務器

q  RDB 很是適用於災難恢復(disaster recovery):它只有一個文件,而且內容都很是緊湊,能夠(在加密後)將它傳送到別的數據中心。app

q  RDB 能夠最大化 Redis 的性能:父進程在保存 RDB 文件時惟一要作的就是 fork 出一個子進程,而後這個子進程就會處理接下來的全部保存工做,父進程無須執行任何磁盤 I/O 操做。ide

q  RDB 在恢復大數據集時的速度比 AOF 的恢復速度要快。工具

2.2 RDB的缺點

q  若是你須要儘可能避免在服務器故障時丟失數據,那麼 RDB 不適合你。 雖然 Redis 容許你設置不一樣的保存點(save point)來控制保存 RDB 文件的頻率, 可是, 由於RDB 文件須要保存整個數據集的狀態, 因此它並非一個輕鬆的操做。 所以你可能會至少 5 分鐘才保存一次 RDB 文件。 在這種狀況下, 一旦發生故障停機, 你就可能會丟失好幾分鐘的數據。

q  每次保存 RDB 的時候,Redis 都要 fork() 出一個子進程,並由子進程來進行實際的持久化工做。 在數據集比較龐大時, fork() 可能會很是耗時,形成服務器在某某毫秒內中止處理客戶端; 若是數據集很是巨大,而且 CPU 時間很是緊張的話,那麼這種中止時間甚至可能會長達整整一秒。 雖然 AOF 重寫也須要進行 fork() ,但不管 AOF 重寫的執行間隔有多長,數據的耐久性都不會有任何損失。

2.3 配置RDB快照

2.3.1 快照文件名

在默認的狀況下, Redis 將數據庫快照保存在名字爲 dump.rdb 的二進制文件中。這是由參數dbfilename來決定的。

2.3.2 快照保存策略

以對 Redis 進行設置, 讓它在「 N 秒內數據集至少有 M 個改動這一條件被知足時, 自動保存一次數據集。

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

save 60 1000

默認配置爲:

save 900 1                     
save 300 10
save 60 10000

若是想要關閉快照功能,則只需將以上配置替換爲:

save ""

2.4 RDB快照運做方式

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

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

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

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

第3章 AOF--追加

3.1 AOF的優勢

q  使用 AOF 持久化會讓 Redis 變得很是耐久(much more durable):你能夠設置不一樣的 fsync 策略,好比無 fsync ,每秒鐘一次 fsync ,或者每次執行寫入命令時 fsync  AOF 的默認策略爲每秒鐘 fsync 一次,在這種配置下,Redis 仍然能夠保持良好的性能,而且就算髮生故障停機,也最多隻會丟失一秒鐘的數據( fsync 會在後臺線程執行,因此主線程能夠繼續努力地處理命令請求)。

q  AOF 文件是一個只進行追加操做的日誌文件(append only log), 所以對 AOF 文件的寫入不須要進行 seek  即便日誌由於某些緣由而包含了未寫入完整的命令(好比寫入時磁盤已滿,寫入中途停機,等等), redis-check-aof 工具也能夠輕易地修復這種問題。

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

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

3.2 AOF的缺點

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

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

q  AOF 在過去曾經發生過這樣的 bug 由於個別命令的緣由,致使 AOF 文件在從新載入時,沒法將數據集恢復成保存時的原樣。 (舉個例子,阻塞命令 BRPOPLPUSH 就曾經引發過這樣的 bug 。) 測試套件裏爲這種狀況添加了測試: 它們會自動生成隨機的、複雜的數據集, 並經過從新載入這些數據來確保一切正常。 雖然這種 bug AOF 文件中並不常見, 可是對比來講, RDB 幾乎是不可能出現這種 bug 的。

3.3 配置AOF

3.3.1 AOF功能開啓

經過修改配置文件來打開AOF功能:

appendonly yes


3.3.2 AOF同步策略

咱們能夠配置 Redis 多久纔將數據 fsync 到磁盤一次。

有三個選項:

q  always

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

q  everysec

每秒 fsync 一次:足夠快(和使用 RDB 持久化差很少),而且在故障時只會丟失 1 秒鐘的數據。推薦(而且也是默認)的措施爲每秒 fsync 一次, 這種 fsync 策略能夠兼顧速度和安全性

q  no

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

具體參數以下:

appendfsync everysec


3.3.3 AOF重寫

由於 AOF 的運做方式是不斷地將命令追加到文件的末尾, 因此隨着寫入命令的不斷增長, AOF 文件的體積也會變得愈來愈大。舉個例子, 若是你對一個計數器調用了 100  INCR  那麼僅僅是爲了保存這個計數器的當前值, AOF 文件就須要使用 100 條記錄(entry)。然而在實際上, 只使用一條 SET 命令已經足以保存計數器的當前值了, 其他 99 條記錄實際上都是多餘的。

爲了處理這種狀況, Redis 支持一種有趣的特性: 能夠在不打斷服務客戶端的狀況下, AOF 文件進行重建(rebuild)。執行 BGREWRITEAOF 命令, Redis 將生成一個新的 AOF 文件, 這個文件包含重建當前數據集所需的最少命令。

auto-aof-rewrite-percentage 100


#<==觸發自動重寫所佔的百分比,0表示禁用自動重寫功能

auto-aof-rewrite-min-size 64mb


#<==指定自動重寫AOF文件的最小大小

3.3.4 AOF修復錯誤校驗

服務器可能在程序正在對 AOF 文件進行寫入時停機, 若是停機形成了 AOF 文件出錯(corrupt), 那麼 Redis 在重啓時會拒絕載入這個 AOF 文件, 從而確保數據的一致性不會被破壞。

當發生這種狀況時, 能夠用如下方法來修復出錯的 AOF 文件:

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

2、使用 Redis 附帶的 redis-check-aof 程序,對原來的 AOF 文件進行修復。

$ redis-check-aof --fix

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

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

配置參數以下:

aof-load-truncated yes
#<==是否加載被截斷(reids出問題時AOF文件可能被截斷)的AOF日誌。設置yes表示加載被截斷的AOF文件,並經過日誌告知用戶;若是設置爲no,則redis拒絕啓動,須要運行redis-check-aof才能啓動服務。

3.3.5 AOF運做方式

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

如下是 AOF 重寫的執行步驟:

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

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

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

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

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

第4章 RDBAOF之間的切換

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

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

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

3、執行如下兩條命令:

redis-cli> CONFIG SET appendonly yes
redis-cli> CONFIG SET save ""

4、確保命令執行以後,數據庫的鍵的數量沒有改變。

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

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

步驟 3 執行的第二條命令用於關閉 RDB 功能。 這一步是可選的, 也能夠同時使用 RDB AOF 這兩種持久化功能。

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

相關文章
相關標籤/搜索