redis(三):redis的兩種持久化方式(RDB與AOF)

一、前言

由於Redis的數據都存放在內存中,如果沒有配置持久化,redis重啓後數據就全丟失了,於是需要開啓redis的持久化功能,將數據保存到磁盤上,當redis重啓後,可以從磁盤中恢復數據。

redis提供兩種方式進行持久化

  1. RDB方式:將Reids在內存中的數據定時進行快照並持久到磁盤上。它是redis默認採用的持久化方式。
  2. AOF方式:將Reids的操作命令以追加的方式寫入文件,當服務器重啓的時候會重新執行這些命令來恢復原始的數據

二、RDB方式

1、RDB介紹

在Redis中RDB持久化的觸發分爲兩種:

  • 自己手動觸發;
  • 根據你所配置的配置文件的策略,達到策略的某些條件時來自動持久化數據;

(1)手動觸發可以使用兩種方式:

save:在Redis主線程中工作,因此會阻塞其他請求操作,應禁止使用。
bgsave:該觸發方式會fork一個子進程,由子進程負責持久化過程,因此阻塞只會發生在fork子進程的時候。

(2)根據配置文件的策略自動觸發:

實際上它和bgsave命令持久化原理是相同的。具體配置如下:

  • RDB持久化條件

以下是redis配置文件的默認配置

save 900 1   #在900秒(15分鐘)之後,如果至少有1個key發生變化,則dump內存快照。

save 300 10    #在300秒(5分鐘)之後,如果至少有10個key發生變化,則dump內存快照。

save 60 10000  #在60秒(1分鐘)之後,如果至少有10000個key發生變化,則dump內存快照。
  1. 可以配置多個條件(每行配置一個條件),每個條件之間是“或”的關係。
  2. 默認情況下,會持久化到dump.rdb文件,並且在redis重啓後,自動讀取其中文件。據悉,通常情況下一千萬的字符串類型鍵,1GB的快照文件,同步到內存中的 時間是20-30秒。
  • 配置dir指定rdb快照文件的位置
# Note that you must specify a directory here, not a file name.
dir ./
  • 配置dbfilename指定rdb快照文件的名稱
# The filename where to dump the DB
dbfilename dump.rdb
2、RDB工作原理

在這裏插入圖片描述
(1)redis調用系統中的fork函數複製一份當前進程的副本(子進程)
(2)父進程繼續接收並處理客戶端發來的命令,而子進程開始將內存中的數據寫入硬盤中的臨時文件。
(3)當子進程寫入完所有數據後會用該臨時文件替換舊的RDB文件,至此,一次快照操作完成。

注意事項
1.redis在進行快照的過程中不會修改RDB文件,只有快照結束後纔會將舊的文件替換成新的,也就是說任何時候RDB文件都是完整的。
2.這就使得我們可以通過定時備份RDB文件來實現redis數據庫的備份, RDB文件是經過壓縮的二進制文件,佔用的空間會小於內存中的數據,更加利於傳輸。

3、RDB優缺點:
  • 缺點:使用RDB方式實現持久化,一旦Redis異常退出,就會丟失最後一次快照以後更改的所有數據。這個時候我們就需要根據具體的應用場景,通過組合設置自動快照條件的方式來將可能發生的數據損失控制在能夠接受範圍。如果數據相對來說比較重要,希望將損失降到最小,則可以使用AOF方式進行持久化
  • 優點: RDB可以最大化Redis的性能:父進程在保存RDB文件時唯一要做的就是fork出一個子進程,然後這個子進程就會處理接下來的所有保存工作,父進程無序執行任何磁盤I/O操作。同時這個也是一個缺點,如果數據集比較大的時候,fork可以能比較耗時,造成服務器在一段時間內停止處理客戶端的請求;

三、AOF方式

1、AOF介紹
  • 默認情況下Redis沒有開啓AOF(append only file)方式的持久化
  • 開啓AOF持久化後每執行一條會更改Redis中的數據的命令,Redis就會將該命令寫入硬盤中的AOF文件,這一過程顯然會降低Redis的性能,但大部分情況下這個影響是能夠接受的,另外使用較快的硬盤可以提高AOF的性能。
  • 可以通過修改redis.conf配置文件中的appendonly參數開啓
appendonly yes
  • AOF文件的保存位置和RDB文件的位置相同,都是通過dir參數設置的。
dir ./
  • 默認的文件名是appendonly.aof,可以通過appendfilename參數修改:
appendfilename appendonly.aof
2、AOF工作原理

Redis每次更改數據的時候, aof機制都會將命令記錄到aof文件,但是實際上由於操作系統的緩存機制,數據並沒有實時寫入到硬盤,而是進入硬盤緩存。再通過硬盤緩存機制去刷新到保存到文件。

三種方式如下:

appendfsync always #每次執行寫入都會進行同步 , 這個是最安全但是是效率比較低的方式。
appendfsync everysec #每秒鐘同步一次,該策略爲AOF的缺省策略。
appendfsync no #從不同步。高效但是數據不會被持久化。

3、AOF重寫原理(優化AOF文件)
  • Redis 可以在 AOF 文件體積變得過大時,自動地在後臺對 AOF 進行重寫
  • 重寫後的新 AOF 文件包含了恢復當前數據集所需的最小命令集合。
  • 整個重寫操作是絕對安全的,因爲 Redis 在創建新 AOF 文件的過程中,會繼續將命令追加到現有的 AOF 文件裏面,即使重寫過程中發生停機,現有的 AOF 文件也不會丟失。 而一旦新 AOF 文件創建完畢,Redis 就會從舊 AOF 文件切換到新 AOF 文件,並開始對新 AOF 文件進行追加操作。
  • AOF 文件有序地保存了對數據庫執行的所有寫入操作, 這些寫入操作以 Redis 協議的格式保存, 因此 AOF 文件的內容非常容易被人讀懂, 對文件進行分析(parse)也很輕鬆。

參數說明:
#auto-aof-rewrite-percentage 100 表示當前aof文件大小超過上一次aof文件大小的百分之多少的時候會進行重寫。如果之前沒有重寫過,以啓動時aof文件大小爲準。
#auto-aof-rewrite-min-size 64mb 限制允許重寫最小aof文件大小,也就是文件大小小於64mb的時候,不需要進行優化。

4、AOF文件損壞以後如何修復

服務器可能在程序正在對 AOF 文件進行寫入時停機, 如果停機造成了 AOF 文件出錯(corrupt), 那麼 Redis 在重啓時會拒絕載入這個 AOF 文件, 從而確保數據的一致性不會被破壞。

當發生這種情況時, 可以用以下方法來修復出錯的 AOF 文件:

1.爲現有的 AOF 文件創建一個備份。
2.使用 Redis 附帶的 redis-check-aof 程序,對原來的 AOF 文件進行修復。
redis-check-aof --fix readonly.aof
3.重啓 Redis 服務器,等待服務器載入修復後的 AOF 文件,並進行數據恢復。

四、從持久化中恢復數據

數據的備份、持久化完成後,如何從這些持久化文件中恢復數據呢?如果一臺服務器上有既有RDB文件,又有AOF文件,優先加載誰呢?

其實想要從這些文件中恢復數據,只需要重新啓動Redis即可。流程如下:
在這裏插入圖片描述
啓動時會先檢查AOF文件是否存在,如果不存在就嘗試加載RDB。那麼爲什麼會優先加載AOF呢?因爲AOF保存的數據更完整,通過上面的分析我們知道AOF基本上最多損失1s的數據。

五、如何選擇RDB和AOF

  • 一般來說,如果對數據的安全性要求非常高的話,應該同時使用兩種持久化功能。
  • 如果可以承受數分鐘以內的數據丟失,那麼可以只使用 RDB 持久化。
  • 有很多用戶都只使用 AOF 持久化, 但並不推薦這種方式: 因爲定時生成 RDB 快照(snapshot)非常便於進行數據庫備份, 並且 RDB 恢復數據集的速度也要比 AOF 恢復的速度要快 。
  • 兩種持久化策略可以同時使用,也可以使用其中一種。如果同時使用的話, 那麼Redis重啓時,會優先使用AOF文件來還原數據。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章