Redis 資料持久化方案的介紹及應用

_天道酬勤_發表於2020-04-05

RDB

原理是fork和cow,fork是指redis通過建立子程式來進行RDB操作,cow指的是copy on write,子程式建立後,父子程式共享資料段,父程式繼續提供讀寫服務,寫髒的頁面資料會逐漸和子程式分離開來

RDB是對Redis中的資料執行週期性的持久化

適合做冷備份

優點

會生成多個資料檔案,每個資料檔案分別都代表了某一時刻Redis裡面的資料,完整的資料運維設定定時任務,定時同步到遠端的伺服器,一旦線上掛了,你想恢復多少分鐘之前的資料,就去遠端拷貝一份之前的資料就行

RDB對Redis的效能影響非常小,因為在同步資料時,他只是fork了一個子程式去做持久化,在資料恢復的時候速度比AOF快

缺點

RDB是快照檔案,都是預設五分鐘甚至更久的時間才會生成一次,意味著這中間五分鐘的資料很可能全部丟失,而AOF則最多丟一秒的資料

RDB在生成資料快照的時候,如果檔案很大,客戶端可能會暫停幾毫米甚至幾秒,如果在高負載的時候正好fork了一個子程式去生成一個大快照,就出大問題了

AOF

對每條寫入命令作為日誌,以append-only的模式寫入一個日誌檔案中,因為這個模式是隻追加的方式,所以沒有任何磁碟定址的開銷,所以很快,類似於mysql中的binlog

適合做熱備

優點

AOF是一秒一次去通過一個後臺的執行緒fsync操作,最多丟這一秒的資料

AOF在對日誌檔案進行操作的時候是以append-only的方式去寫,只是追加的方式寫資料,自然寫入效能很好,檔案也不容易損壞

AOF的日誌是通過一個叫非常可讀的方式記錄,這樣的特性就適合做災難性資料誤刪除的緊急恢復

缺點

一樣的資料,AOF檔案比RDB要大

AOF開啟後,Redis支援寫的QPS會比RDB支援寫的低,當然即使這樣效能還是很高

實際應用

RDB做映象全量持久化,AOF做增量持久化

因為RDB會耗費較長時間,不夠實時,在停機的時候會導致大量丟失資料,所以需要AOF來配合使用

在Redis例項重啟時,會使用RDB持久化檔案重新構建記憶體,再使用AOF重放近期的操作指令來實現完整恢復重啟之前的狀態

資料丟失問題

例如伺服器掉電是否會丟失資料

取決於AOF日誌sync屬性的配置,如果不要求效能,在每條寫指令時都sync一下磁碟,就不會丟失資料

但是實際生產中,通常對高效能有要求,一般都是用定時sync,例如1秒1次,這個時候最多會丟失1s的資料

RDB和AOF對比

同步機制

Redis可以使用主從同步,從從同步。

第一次同步時,主節點做一次bgsave,並同時將後續修改操作記錄到記憶體buffer,待完成後將RDB檔案全量同步到複製節點,複製節點接受完成後將RDB映象載入到記憶體。

載入完成後,再通知主節點將期間修改的操作記錄同步到複製節點進行重放就完成了同步過程。

後續的增量資料通過AOF日誌同步即可,有點類似資料庫的binlog

命令說明

SAVE

時間複雜度: O(N), N 為要儲存到資料庫中的 key 的數量。

功能說明

SAVE 命令執行一個同步儲存操作,將當前 Redis 例項的所有資料快照(snapshot)以 RDB 檔案的形式儲存到硬碟。

一般來說,在生產環境很少執行 SAVE 操作,因為它會阻塞所有客戶端,儲存資料庫的任務通常由 BGSAVE 命令非同步地執行。然而,如果負責儲存資料的後臺子程式不幸出現問題時, SAVE 可以作為儲存資料的最後手段來使用

返回值

儲存成功時返回ok

示例

redis> SAVE
OK
複製程式碼

BGSAVE

時間複雜度: O(N), N為要儲存到資料庫中的key的數量

功能說明

在後臺非同步(Asynchronously)儲存當前資料庫的資料到磁碟

BGSAVE 命令執行之後立即返回 OK ,然後 Redis fork 出一個新子程式,原來的 Redis 程式(父程式)繼續處理客戶端請求,而子程式則負責將資料儲存到磁碟,然後退出。

BGREWRITEAOF

時間複雜度: O(N)

功能說明

執行一個AOF檔案重寫操作。重寫會建立一個當前 AOF 檔案的體積優化版本。

即使 BGREWRITEAOF 執行失敗,也不會有任何資料丟失,因為舊的 AOF 檔案在 BGREWRITEAOF 成功之前不會被修改。

重寫操作只會在沒有其他持久化工作在後臺執行時被觸發,也就是說:

如果 Redis 的子程式正在執行快照的儲存工作,那麼 AOF 重寫的操作會被預定(scheduled),等到儲存工作完成之後再執行 AOF 重寫。在這種情況下, BGREWRITEAOF 的返回值仍然是 OK ,但還會加上一條額外的資訊,說明 BGREWRITEAOF 要等到儲存操作完成之後才能執行。在 Redis 2.6 或以上的版本,可以使用 INFO [section] 命令檢視 BGREWRITEAOF 是否被預定。

如果已經有別的 AOF 檔案重寫在執行,那麼 BGREWRITEAOF 返回一個錯誤,並且這個新的 BGREWRITEAOF 請求也不會被預定到下次執行。

從 Redis 2.4 開始, AOF 重寫由 Redis 自行觸發, BGREWRITEAOF 僅僅用於手動觸發重寫操作。

返回值

反饋資訊

示例

redis> BGREWRITEAOF
Background append only file rewriting started
複製程式碼

LASTSAVE

時間複雜度: O(1)

功能說明

返回最近一次 Redis 成功將資料儲存到磁碟上的時間,以 UNIX 時間戳格式表示

返回值

一個 UNIX 時間戳

示例

redis> LASTSAVE
(integer) 1324043588
複製程式碼

相關文章