本文首發於 Redis 持久化(persistence)技術口袋書,轉載請註明出處。
本文講解 Redis 數據庫的數據持久化解決方案。php
測試環境:html
Redis 提供兩種持久化解決方案:RDB 持久化和 AOF 持久化。git
要點:github
RDB 持久化:能夠在指定時間間隔內,生成數據集在這個時間點的快照。
AOF 持久化:經過記錄服務器執行的全部寫操做命令,在服務器重啓時,經過從新執行這些命令來還原數據。redis
採用 RDB 持久化方案時,Redis 會每隔一段時間對數據集進行快照備份,換句話說這種方案在服務器發生故障時可能形成數據的丟失。因此,若是對數據的完整性有比較強烈的要求,可能不太適用這種備份方案,即它適用於作數據的備份。shell
咱們已經知道,採用 RDB 持久化方案會每隔一段時間對數據進行備份,那麼這個時間段如何肯定呢?數據庫
咱們能夠到 redis.windows.conf 配置文件的 SNAPSHOTTING 配置節點獲取答案,默認狀況下 Redis 採用三種持久化策略:windows
save 900 1 save 300 10 save 60 10000
這裏的 save 指令表示「在 x 秒內有 n 個及以上鍵被改動」則會自動保存一次數據集,好比配置中的 save 60 10000 表示若是在 60 秒內有 10000 個及以上的鍵被改動時則執行保存數據集操做。緩存
咱們在啓動 Redis 服務時,服務器會讀取配置文件中的配置,因此 RDB 持久化策略會自動啓動,當知足條件時會執行持久化處理。安全
不過,有時咱們可能須要手動的執行 RDB 持久化處理,那麼 Redis 有沒有提供相似的方法呢?
答案是有的,咱們可使用 [SAVE]](http://redisdoc.com/server/sa...(這裏不是配置文件中的 save 指令) 或 BGSAVE 命令,來手動執行 RDB 持久化處理。
雖然,save 和 bgsave 均可以手動的執行 RDB 持久化處理。可是它們的工做模式徹底不一樣。
注意:雖然經過 SAVE 命令能夠執行 RDB 持久化處理,可是它的運行原理同自動持久化中的 save 指令是徹底不一樣的, save 指令的工做原理同 BGSAVE 指令。
在 RDB 持久化策略中,咱們引入了「快照」的概念,即「在 x 秒內有 n 個及以上鍵被改動」則執行持久化處理。
- Redis 調用 fork() ,同時擁有父進程和子進程。
- 子進程將數據集寫入到一個臨時 RDB 文件中。
- 當子進程完成對新 RDB 文件的寫入時,Redis 用新 RDB 文件替換原來的 RDB 文件,並刪除舊的 RDB 文件。
摘自 Redis 持久化。
經過 RDB 持久化方案的學習,咱們知道它可能致使數據丟失,若是你的項目忍不了數據丟失的問題,那麼可能就須要使用 AOF 持久化方案。
AOF(append only file):只進行追加操做的文件。默認狀況下,Redis 會禁用 AOF 重寫,無需開啓咱們須要到配置文件中將 appendonly 指令配置爲 yes(默認:no 不啓用)。
啓用 AOF 持久化方案後,當咱們執行相似 SET 設置(或修改)命令時,Redis 會將命令以 Redis 通訊協議 文本保存到 appendonly.aof 文件中。
AOF 持久化方案提供 3 種不一樣時間策略將數據同步到磁盤中,同步策略經過 appendfsync 指令完成:
使用是推薦採用默認的 everysec 每秒同步策略,兼顧安全與效率。
摘自 Redis 持久化。
咱們知道 AOF 的運行原理是不斷的將寫入的命令以 Redis 通訊協議的數據格式追加到 .aof 文件末尾,這就會致使文件的體積不斷增大。
若是全部的命令徹底不一樣到沒有關係。
可是,若是命令處理相似計數器的功能,好比執行 100 次 INCR(incr counter) 處理,AOF 文件會保存所有的 INCR 命令的執行記錄,但實際上咱們知道這些處理的結果同 set counter 100 並沒有二致。這就致使咱們的 .aof 多存儲了 99 條命令記錄。
這時,咱們就可使用 Redis 提供的 BGREWRITEAOF 重寫命令,將 AOF 文件進行重寫優化。
舉例:
SET name 'liugongzi' SET age 18 SET name 'liugongzi handsome'
AOF 文件將這些寫入命令保存到(appendonly.aof)文件中,內容以下:
*2 $6 SELECT $1 0 *3 $3 set $4 name $9 liugongzi *3 $3 set $3 age $2 18 *3 $3 set $4 name $18 liugongzi handsome
寫入的內容徹底遵循 Redis 通訊協議。經過示例,咱們知道雖然咱們執行了兩次 set name 操做,但最終 Redis 保存的 name 值是 liugongzi handsome。也就是說第一次 set name 其實並沒有必要。
如今咱們經過 BGREWRITEAOF 命令對文件進行重寫處理:
127.0.0.1:6380> BGREWRITEAOF Background append only file rewriting started
重寫完成後的 AOF 文件內容以下:
*2 $6 SELECT $1 0 *3 $3 SET $3 age $2 18 *3 $3 SET $4 name $18 liugongzi handsome
經過對比重寫先後的文件內容,能夠發現 Redis 將第一次的 set name 'liugongzi' 操做給刪出掉了。這樣就達到優化 AOF 文件的目的。
補充一句 AOF 重寫,並非對 AOF 文件進行重寫,而是依據 Redis 在內存中當前的鍵值進行重寫的。
摘自 Redis 持久化。
經過前面的學習咱們瞭解到 Redis 是如何執行 RDB 和 AOF 持久化處理的,如今咱們簡單瞭解下 Redis 是如何恢復 RDB 或 AOF 備份中的數據。
咱們知道 Redis 是一種內存型的 NoSQL 數據庫(或者說數據結構),當服務重啓或宕機都會致使內存中的數據丟失。
因此,當 Redis 服務器重啓或恢復時,它會進行讀取 RDB 或 AOF 文件(若是存在的話)處理,將文件中的數據從新載入內存實現數據恢復操做。
Redis 數據恢復採用兩套恢復方案:
這個很好理解,由於 AOF 持久化方案的數據保存是秒級的,因此相對於 RDB 持久化數據更完整,因此在啓動 Redis 服務器是,會在 AOF 啓用時有限載入 AOF 文件進行數據還原。
到這裏,相信你對 Redis 持久化已經有了至關大瞭解了,這節開始咱們將學習 Redis 配置文件,看看如何使用 RDB 和 AOF 持久化功能。
Redis 服務器配置文件默認是 redis.windows.conf:
RDB 配置位於 SNAPSHOTTING 配置節點。
#save 900 1 #save 300 10 #save 60 10000
經過 rdbcompression 指令完成,默認 yes 進行壓縮。
使用 dbfilename 指令,默認值 dump.rdb。
使用 dir 指令,默認值 your_redis_path。另外 AOF 備份數據一樣會保存到該目錄下。
AOF 配置位於 APPEND ONLY MODE 配置節點。
開啓 AOF 持久化功能,經過 appendonly 指令完成,取值範圍 yes / no,默認:no 不開啓 AOF 重寫。
由 appendfilename 指令完成,默認值 appendonly.aof。
請參考前文 appendfsync 指令說明。
以前咱們經過使用命令 BGREWRITEAOF 對 AOF 執行重寫,可是當咱們啓用 AOF 持久化功能後,Redis 默認會啓用 AOF 重寫優化,這個工做有兩條指令完成:
auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
auto-aof-rewrite-percentage 指令表示,本次執行 AOF 重寫時,當 AOF 文件的大小是上次執行重寫時文件的百分之多少才能夠自動重寫。默認: 100 表示本次重寫時的 AOF 文件是上次 2 倍能夠自動重寫。
auto-aof-rewrite-min-size 這個指令用於設置進行 AOF 文件自動重寫的最小文件大小。
換言之,這兩條配置表示:當 AOF 文件大小達到 64mb 時,纔開始自動進行重寫。下一次只有當文件大小需達到 128 mb 才能再次重寫,以此類推。
當咱們的 Redis 服務器宕機時,可能致使 AOF 文件的尾部數據不完整,在重啓 Redis 服務器可能致使數據不一致。此時能夠經過:
aof-load-truncated 指令在啓動 Redis 自動修復文件。它的取值範圍是 yes / no,默認爲 yes 重啓時自動修復。
一樣的咱們也能夠經過 redis-check-aof --fix 修復工具手動進行修復。