分布式緩存Redis的持久化方式RDB和AOF


一、前言

  Redis支持兩種方式的持久化,RDB和AOF。RDB會根據指定的規則“定時”將內存中的數據存儲到硬盤上,AOF會在每次執行命令后將命令本身記錄下來。兩種持久化方式可以單獨使用其中一種,但更多情況下是兩種結合使用。

二、RDB

  RDB方式的持久化是通過快照完成的,當符合一定條件的時候Redis會自動將內存中的所有數據生成一份副本並存儲在硬盤上,這個過程即為“快照”。Redis會在以下四種情況下對數據進行快照:

  • 根據配置規則進行自動快照;
  • 用戶指定SAVE或BGSAVE命令;
  • 執行FLUSHALL命令;
  • 指定復制時;

  1.根據配置規則進行自動快照

  Redis允許用戶自定義快照條件,當符合快照條件的時候,Redis會自動進行快照操作。進行快照的條件可以由用戶的配置文件中自定義,有兩個參數構成:時間窗口M和改動的鍵的個數N。每當時間M內被更改的鍵的個數大於N時,即符合自動快照的條件。例如Redis的安裝目錄中包含的樣例配置文件中預置的3個條件:

 

   每條快照條件占一行,並且以save參數開頭。同時可以存在多個條件,條件之間是or的關系。就這個例子來說,save 900 1 的意思是在十五分鍾內(900秒)內有一個或者以上的鍵被更改則進行快照。同理,save 300 10 表示在300秒內至少有十個鍵被修改則進行快照。

  2.用戶指定save或bgsave命令

  除了讓Redis自動進行快照外,當進行服務重啟、手動遷移以及備份時我們也會需要手動執行快照操作。Redis提供了兩個命令:

  save:當執行save命令的時候,Redis同步地進行快照操作,在快照執行地過程中阻塞所有來自客戶端的請求。當數據庫中的數據比較多的時候,這一過程會導致Redis較長時間不能響應,所以要盡量避免在生產環境使用。

127.0.0.1:6379> save
OK

  bgsave:需要手動執行快照時推薦使用bgsave命令。bgsave命令可以在后台異步地進行快照操作,快照地同時服務器還可以繼續響應來自客戶端的請求。執行bgsave后Redis會立即返回Background saving started表示開始執行快照操作。如果想知道快照是否完成,可以通過lastsave命令獲取最后一次成功執行快照地時間,返回一個unix時間戳,如:

127.0.0.1:6379> bgsave
Background saving started
127.0.0.1:6379> lastsave
(integer) 1580356962

  3.執行flushall命令

  當執行flushall命令時,Redis會清除數據庫中的所有數據。需要注意的是,不論清空數據庫的過程是否觸發了自動快照的條件,只要自動快照條件不為空,Redis就會執行一次快照操作。當沒有自定義的自動快照條件時,執行flushall則不會進行自動快照。

  4.執行復制

  當設置了主從模式,Redis會在復制初始化時進行自動快照。

  5.快照原理

  理清Redis實現快照的過程對我們了解快照文件的特性有很大的幫助。Redis默認會將快照文件存儲在Redis當前進程的工作目錄中的dump.rdb文件中,可以通過配置dir和dbfilename兩個參數分別指定快照文件的存儲路徑和文件名。快照過程如下:

  • Redis使用fork函數復制一份當前進程(父進程)的副本(子進程)。
  • 父進程繼續接收並處理客戶端發來的命令,而子進程開始將內存中的數據寫入硬盤中的臨時文件。‘
  • 當子進程寫入完所有的數據后會用臨時文件替換舊的RDB文件,至此一次快照操作完成。

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

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

  通過RDB方式實現持久化,一旦Redis異常退出,就會丟失最后一次快照以后更改的所有數據。這就需要開發者根據實際情況,通過組合設置自動快照條件的方式來將可能發生的數據損失控制在能夠接受的范圍內。例如,使用Redis存儲緩存數據時,丟失最近幾秒的數據或者丟失最近更新的幾十個鍵問題不大。要是數據十分重要,希望將損失降低到最小,就可以使用AOF方式進行持久化。

三、AOF方式

  當使用Redis存儲非臨時數據時,一般需要打開AOF方式持久化來降低進程中止導致的數據丟失。AOF可以將Redis執行的每一條寫命令追加到硬盤文件中,這一過程顯然會降低Redis的性能,但是大部分情況下是可以接受的,另外使用較快的硬盤可以提高AOF的性能。

  1.開啟AOF

  默認情況下Redis沒有開啟AOF方式的持久化,可以通過配置文件的appendonly參數啟動,直接修改配置文件可能沒有appendonly.aof文件,需要通過下列語句啟動:

127.0.0.1:6379> config set appendonly yes
OK

   開啟AOF持久化后每執行一條更改Redis中的數據的命令,Redis就會將該命令寫入硬盤中的AOF文件。AOF文件的保存位置和RDB文件的位置相同,都是通過dir參數設置的,默認文件名是appendonly.aof,可以通過appendfilename參數修改。

   2.AOF的實現

  AOF文件以純文本的形式記錄了Redis執行的寫命令,例如在開啟AOF持久化的情況下執行了如下幾個命令:

127.0.0.1:6379> set day 1
OK
127.0.0.1:6379> set day 2
OK
127.0.0.1:6379> get day
"2"

  appendonly.aof文件內的數據如下:

*2
$6
SELECT
$1
0
*3
$3
SET
$3
day
$1
2

  從上可以看到AOF文件的內容正是Redis客戶端向Redis發送的原始通信協議的內容。如果執行的Redis命令越多那這個文件就越大,即使內存中實際的數據可能並沒有多少。所以我們可以通過設置配置文件,來讓Redis在達到特定條件時自動重寫Redis文件:

auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

  auto-aof-rewirte-percentage參數的意義時當目前的AOF文件大小超過上一次AOF重寫時的文件大小的百分之多少時會再次進行重寫,如果之前沒有重寫過,則以啟動時的AOF文件大小為依據。

  auto-aof-rewirte-min-size參數是限制允許重寫的AOF文件最小的大小。

  在啟動Redis時會從AOF文件中逐個執行命令,所以比RDB速度會慢。

  3.同步硬盤數據

  雖然每次執行更改Redis數據庫的命令時,AOF都會記錄在AOF文件中,但是事實上,由於操作系統的緩存機制,數據並沒有真正的寫入硬盤,而是進入了系統的硬盤緩存。在默認情況下系統每30秒會執行一次同步操作,以便將硬盤緩存中的內容真正寫入硬盤,所以在這之前系統異常會導致數丟失,所以我們需要在Redis的配置文件中設置同步時機:

# appendfsync always
appendfsync everysec
# appendfsync no

  默認情況下Redis采用everysec規則,即每秒執行一次同步。always表示每次執行寫入都同步,這最安全卻也最慢。no表示不主動同步,由操作系統自動來做。

  Redis允許同時開啟AOF和RDB模式,同時啟動的情況下,Redis會采用AOF的數據來恢復,因為它可能丟失的數據最少。


免責聲明!

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



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