redis的持久化之RDB的配置和原理


        Redis優秀的性能是由於其將所有的數據都存儲在內存中,同樣memcached也是這樣做的,內存中的數據會在服務器重啟后就沒有了,也就是不能保證持久化。但是為什么Redis能夠脫穎而出呢,很大程度上是因為Redis有出色的持久化機制,能夠保證服務器重啟后,數據不會丟失。Redis持久化是將內存中的數據寫入到磁盤(也就是文件)中。下面來看看Redis是如何持久化的。

       Redis支持兩種方式的持久化,一種是RDB方式,一種是AOF方式。這兩種方式可以單獨使用其中一種,或者混合使用。 

RDB方式介紹

        RDB方式是通過快照完成的,當符合一定條件時Redis會自動將內存中的所有數據進行快照,並且存儲到硬盤上。就像拍照一樣,將這一瞬間的所有東西都保存下來。進行快照的條件在配置文件中指定。主要有兩個參數構成:時間和改動的鍵值的個數,即當在指定時間內被更改的鍵的個數大於執行數值時,就會進行快照。RDB是Redis的默認持久化方式。 

RDB方式配置

找到Redis的配置文件:redis.conf

1) 設置觸發條件:

 

這里寫圖片描述 

 

 

這里寫圖片描述

 

2) 設置rdb文件路徑

默認rdb文件存放路徑是當前目錄,文件名是:dump.rdb。可以在配置文件中修改路徑和文件名,分別是dir和dbfilename

 

這里寫圖片描述

 

Redis啟動后會讀取RDB快照文件,將數據從硬盤載入到內存,一般情況下1GB的快照文件載入到內存的時間大約20-30秒鍾。

當條件滿足,redis需要執行RDB的時候,服務器會執行以下操作:

1. redis調用系統函數fork() ,創建一個子進程進行持久化。

 2.子進程將數據集寫入到一個臨時 RDB 文件中(持久化,也就是將內存中的數據寫入臨時文件)。

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

注:fork的作用是復制一個與當前進程一樣的進程。新進程的所有數據(變量、環境變量、程序計數器等)數值都和原進程一致,但是是一個全新的進程,並作為原進程的子進程


在執行fork的時候操作系統(類Unix操作系統)會使用寫時復制(copy-on-write)策略,即fork函數發生的一刻父子進程共享同一內存數據,當父進程要更改其中某片數據時(如執行一個寫命令 ),操作系統會將該片數據復制一份以保證子進程的數據不受影響,所以新的RDB文件存儲的是執行fork那一刻的內存數據。

Redis在進行快照的過程中不會修改RDB文件,只有快照結束后才會將舊的文件替換成新的,也就是說任何時候RDB文件都是完整的。這使得我們可以通過定時備份RDB文件來實 現Redis數據庫備份。RDB文件是經過壓縮(可以配置rdbcompression參數以禁用壓縮節省CPU占用)的二進制格式,所以占用的空間會小於內存中的數據大小,更加利於傳輸。

除了自動快照,還可以手動發送SAVE或BGSAVE命令讓Redis執行快照,兩個命令的區別在於,前者是由主進程進行快照操作,會阻塞住其他請求,后者會通過fork子進程進行快照操作。 

        Redis啟動后會讀取RDB快照文件,將數據從硬盤載入到內存。根據數據量大小與結構和服務器性能不同,這個時間也不同。通常將一個記錄一千萬個字符串類型鍵、大小為1GB的快照文件載入到內 存中需要花費20~30秒鍾。 

         通過RDB方式實現持久化,一旦Redis異常退出,就會丟失最后一次快照以后更改的所有數據。這就需要開發者根據具體的應用場合,通過組合設置自動快照條件的方式來將可能發生的數據損失控制在能夠接受的范圍。如果數據很重要以至於無法承受任何損失,則可以考慮使用AOF方式進行持久化。

 

RDB的優點是:

 1.RDB是一個非常緊湊(compact)的文件,它保存了redis 在某個時間點上的數據集。這種文件非常適合用於進行備份和災難恢復(將持久化到硬盤中的文件恢復即可)。

 2.生成RDB文件的時候,redis主進程會fork()一個子進程來處理所有保存工作,主進程不需要進行任何磁盤IO操作。

 3.RDB 在恢復大數據集時的速度比 AOF 的恢復速度要快。

 

RDB缺點:

 1.如果你需要盡量避免在服務器故障時丟失數據,那么RDB 不適合你。 雖然Redis 允許你設置不同的保存點(save point)來控制保存 RDB 文件的頻率, 但是, 因為RDB 文件需要保存整個數據集的狀態, 所以它並不是一個輕松的操作。 因此你可能會至少 5 分鍾才保存一次 RDB 文件。 在這種情況下, 一旦發生故障停機, 你就可能會丟失好幾分鍾的數據(最后一次的數據)。

2.每次保存 RDB 的時候,Redis 都要 fork() 出一個子進程,並由子進程來進行實際的持久化工作。 在數據集比較龐大時, fork() 可能會非常耗時,造成服務器在某某毫秒內停止處理客戶端; 如果數據集非常巨大,並且 CPU 時間非常緊張的話,那么這種停止時間甚至可能會長達整整一秒。 雖然 AOF 重寫也需要進行 fork() ,但無論 AOF 重寫的執行間隔有多長,數據的耐久性都不會有任何損失。

 

參考:https://blog.csdn.net/u010028869/article/details/51792197

     https://blog.csdn.net/aitangyong/article/details/52045251

 


免責聲明!

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



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