redis是如何做到持久化的?


Redis持久化備份數據的方式有兩種:RDB(Redis DataBase) 、 AOF(Append Only  File).

 

什么是RDB

在指定時間間隔內,將內存中的數據集快照寫入磁盤,也就是Snapshot快照,它恢復時是將快照文件直接讀到內存中,來達到恢復數據的。

 

 如何持久化

Redis會單獨創建(fork)一個子進程來進行持久化,會先將數據寫進一個臨時文件中,等到持久化過程結束了,再用這個臨時文件替換上次持久化好的文件。在這個過程中,只有子進程來負責IO操作,主進程仍然處理客戶端的請求,這就確保了極高的性能。

 

 Snapshot

在默認情況下, Redis 將數據庫快照保存在名字為 dump.rdb 的二進制文件中。通過觸發快照的形式,來做到將指定時間間隔內的數據持久化到dump.rdb。例如,可以2分鍾內持久化一次,將對數據庫的寫操作,備份到磁盤上的dump.rdb。如何觸發持久化呢?可以通過查看或者設置redis.conf配置文件來指定觸發規則。

以下是redis配置文件的觸發快照的默認配置 

 

RDB優點與缺點

優點

如果要進行大規模數據的恢復,RDB方式要比AOF方式恢復速度要快。
RDB可以最大化Redis性能,父進程做的就是fork子進程,然后繼續接受客戶端請求,讓子進程負責持久化操作,父進程無需進行IO操作。
RDB是一個非常緊湊(compact)的文件,它保存了某個時間點的數據集,非常適合用作備份,同時也非常適合用作災難性恢復,它只有一個文件,內容緊湊,通過備份原文件到本機外的其他主機上,一旦本機發生宕機,就能將備份文件復制到redis安裝目錄下,通過啟用服務就能完成數據的恢復。

缺點

RDB這種持久化方式不太適應對數據完整性要求嚴格的情況,因為,盡管我們可以用過修改快照實現持久化的頻率,但是要持久化的數據是一段時間內的整個數據集的狀態,如果在還沒有觸發快照時,本機就宕機了,那么對數據庫所做的寫操作就隨之而消失了並沒有持久化本地dump.rdb文件中。
每次進行RDB時,父進程都會fork一個子進程,由子進程來進行實際的持久化操作,如果數據集龐大,那么fork出子進程的這個過程將是非常耗時的,就會出現服務器暫停客戶端請求,將內存中的數據復制一份給子進程,讓子進程進行持久化操作。

 

 

什么是AOF

以日志的形式記錄Redis每一個寫操作,將Redis執行過的所有寫指令記錄下來(讀操作不記錄),只許追加文件不可以改寫文件,redis啟動之后會讀取appendonly.aof文件來實現重新恢復數據,完成恢復數據的工作。默認不開啟,需要將redis.conf中的appendonly  no改為yes啟動Redis。

 

持久化


Redis的AOF是如何做到持久化的呢?從配置文件中,我們可以發現

appendfsync always:每修改同步,每一次發生數據變更都會持久化到磁盤上,性能較差,但數據完整性較好。

appendfsync everysec: 每秒同步,每秒內記錄操作,異步操作,如果一秒內宕機,有數據丟失。

appendfsync no:不同步。

 

數據恢復

重啟Redis時,如果dump.rdb與appendfsync.aof同時都存在時,Redis會自動讀取appendfsync.aof文件,通過該文件中對數據庫的日志操作,來實現數據的恢復。當然如果該文件被破壞,我們可以通過redis-check-aof工具來修復,如redis-check-aof --fix能修復破損的appendfsync.aof文件,當然如果dump.rdb文件有破損,我們也可以用redis-check-rdb工具來修復,如果appendfsync.aof文件破損了,是啟動不客戶端的,也就是無法完成數據的恢復。

重寫
當然如果AOF 文件一直被追加,這就可能導致AOF文件過於龐大。因此,為了避免這種狀況,Redis新增了重寫機制,當AOF文件的大小超過所指定的閾值時,Redis會自動啟用AOF文件的內容壓縮,只保留可以恢復數據的最小指令集,可以使用命令bgrewiteaof。

重寫原理:AOF文件持續增長過大時,會fork出一條新進程來將文件重寫(也是臨時文件最后再rename),遍歷新進程的內存中的數據,每條記錄都會有一條set語句,重寫aof文件的操作,並沒有讀取舊的aof文件,而是將整個內存中的數據庫內容用命令的方式重寫了一個新的aof文件,有點類似於快照。

觸發機制:Redis會記錄上一次重寫時的AOF大小,默認配置是當AOF文件大小是上一次的一倍並且大於64m時,會觸發從寫機制。

配置文件如下:

 

優點

AOF有着多種持久化策略:
appendfsync always:每修改同步,每一次發生數據變更都會持久化到磁盤上,性能較差,但數據完整性較好。

appendfsync everysec: 每秒同步,每秒內記錄操作,異步操作,如果一秒內宕機,有數據丟失。

appendfsync no:不同步。

 

AOF文件是一個只進行追加操作的日志文件,對文件寫入不需要進行seek,即使在追加的過程中,寫入了不完整的命令(例如:磁盤已滿),可以使用redis-check-aof工具可以修復這種問題

Redis可以在AOF文件變得過大時,會自動地在后台對AOF進行重寫:重寫后的新的AOF文件包含了恢復當前數據集所需的最小命令集合。整個重寫操作是絕對安全的,因為Redis在創建AOF文件的過程中,會繼續將命令追加到現有的AOF文件中,即使在重寫的過程中發生宕機,現有的AOF文件也不會丟失。一旦新AOF文件創建完畢,Redis就會從舊的AOF文件切換到新的AOF文件,並對新的AOF文件進行追加操作。

AOF文件有序地保存了對數據庫執行的所有寫入操作。這些寫入操作一Redis協議的格式保存,易於對文件進行分析;例如,如果不小心執行了FLUSHALL命令,但只要AOF文件未被重寫,通過停止服務器,移除AOF文件末尾的FLUSHALL命令,重啟服務器就能達到FLUSHALL執行之前的狀態。

 

 缺點

對於相同的數據集來說,AOF文件要比RDB文件大。
根據所使用的持久化策略來說,AOF的速度要慢與RDB。一般情況下,每秒同步策略效果較好。不使用同步策略的情況下,AOF與RDB速度一樣快。
 RDB與AOF如何選擇
一般來說,如果想達到足以媲美PostgreSQL的數據安全性,應該同時使用兩種持久化方式。
有很多用戶都只使用 AOF 持久化, 但我們並不推薦這種方式: 因為定時生成 RDB 快照(snapshot)非常便於進行數據庫備份, 並且 RDB 恢復數據集的速度也要比 AOF 恢復的速度要快, 除此之外, 使用 RDB 還可以避免之前提到的 AOF 程序的 bug。
如果可以承受輸分鍾內的數據丟失,可以只使用RDB持久化。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM