Redis持久化儲存——>RDB & AOF

嗨,阿良發表於2020-08-12

Redis中兩種持久化儲存機制RDB和AOF

redis是一個記憶體資料庫,資料儲存在記憶體中,但是我們都知道記憶體的資料變化是很快的,也容易發生丟失。幸好Redis還為我們提供了持久化的機制,分別是RDB(Redis DataBase)和AOF(Append Only File)。

在這裡假設你已經瞭解了redis的基礎語法,某字母網站都有很好的教程,可以去看。基本使用的文章就不寫了,都是一些常用的命令。

下面針對這兩種方式來介紹一下。由淺入深。

一、持久化流程

既然redis的資料可以儲存在磁碟上,那麼這個流程是什麼樣的呢?

會經過如下五個過程:

(1)客戶端向服務端傳送寫操作(資料在客戶端的記憶體中)。

(2)資料庫服務端接收到寫請求的資料(資料在服務端的記憶體中)。

(3)服務端呼叫write這個系統呼叫,將資料往磁碟上寫(資料在系統記憶體的緩衝區中)。

(4)作業系統將緩衝區中的資料轉移到磁碟控制器上(資料在磁碟快取中)。

(5)磁碟控制器將資料寫到磁碟的物理介質中(資料真正落到磁碟上)。

這5個過程是在理想條件下的一個正常儲存流程,但是在大多數情況下,我們的機器等等都會有各種各樣的故障,這裡劃分了兩種情況:

  • (1)Redis資料庫發生故障,只要在上面的第三步執行完畢,那麼就可以持久化儲存,剩下的兩步由作業系統替我們完成。

  • (2)作業系統發生故障,必須上面5步都完成才可以。

在這裡只考慮了儲存的過程可能發生的故障,其實儲存的資料也有可能發生損壞,需要一定的恢復機制,不過在這裡就不再延伸了。現在主要考慮的是redis如何來實現上面5個儲存磁碟的步驟。它提供了兩種策略機制,也就是RDB和AOF。

二、RDB機制

RDB其實就是把資料以快照的形式儲存在磁碟上。什麼是快照呢,你可以理解成把當前時刻的資料拍成一張照片儲存下來。

RDB持久化是指在指定的時間間隔內將記憶體中的資料集快照寫入磁碟。也是預設的持久化方式,這種方式就是將記憶體中資料以快照的方式寫入到二進位制檔案中,預設的檔名為dump.rdb

在我們安裝了redis之後,所有的配置都是在redis.conf檔案中,裡面儲存了RDB和AOF兩種持久化機制的各種配置。

既然RDB機制是通過把某個時刻的所有資料生成一個快照來儲存,那麼就應該有一種觸發機制,l來實現這個過程。對於RDB來說,提供了三種機制:save、bgsave、自動化。我們分別來看一下:

1、save命令觸發方式

該命令會阻塞當前Redis伺服器,執行save命令期間,Redis不能處理其他命令,直到RDB過程完成為止。具體流程如下:

執行完成時如果存在舊的RDB檔案,就把新的替代掉舊的。我們的客戶端可能有幾萬或者是幾十萬,故這種方式顯然不可取。

2、bgsave觸發方式

執行該命令時,Redis會在後臺非同步進行快照操作,快照同時還可以響應客戶端請求。具體流程如下:

具體操作是Redis程式執行fork操作建立子程式,RDB持久化過程由子程式負責,完成後自動結束。阻塞只發生在fork階段,一般時間很短。基本上 Redis 內部所有的RDB操作都是採用 bgsave 命令。

3、二者比較

4、自動化觸發

自動觸發是由修改配置檔案來完成的。在redis.conf配置檔案中,裡面有如下配置,我們可以去設定:

1、save:這裡是用來配置觸發 Redis的 RDB 持久化條件,也就是什麼時候將記憶體中的資料儲存到硬碟。比如“save m n”。表示m秒內資料集存在n次修改時,自動觸發bgsave。

預設如下配置:

 '#'  表示900 秒內如果至少有1個key的值發生變化,則儲存save 900 
'1#'  表示300 秒內如果至少有10個key的值變化,則儲存save 300 
'10#' 表示60 秒內如果至少有10000個key的值變化,則儲存save 60 10000

不需要持久化,那麼你可以註釋掉所有的 save 行來停用儲存功能。

2、'stop-writes-on-bgsave-error':預設值為yes。當啟用了RDB且最後一次後臺儲存資料失敗時,Redis是否停止接收資料,這會讓使用者意識到資料沒有正確持久化到磁碟上,否則沒有人會注意到災難(disaster)發生了。如果Redis重啟了,那麼又可以重新開始接收資料了

3、'rdbcompression':預設值是yes。對於儲存到磁碟中的快照,可以設定是否進行壓縮儲存。

4、'rdbchecksum':預設值是yes。在儲存快照後,我們還可以讓redis使用CRC64演算法來進行資料校驗,但是這樣做會增加大約10%的效能消耗,如果希望獲取到最大的效能提升,可以關閉此功能。

5、'dbfilename':設定快照的檔名,預設是 dump.rdb

6、'dir':設定快照檔案的存放路徑,這個配置項一定是個目錄,而不能是檔名。

我們可以修改這些配置來實現我們想要的效果。

4、RDB 的優勢和劣勢

優勢:

(1)RDB檔案緊湊,全量備份,非常適合用於進行備份和災難恢復。

(2)生成RDB檔案的時候,redis主程式會fork()一個子程式來處理所有儲存工作,主程式不需要進行任何磁碟IO操作。

(3)RDB 在恢復大資料集時的速度比 AOF 的恢復速度要快。

劣勢:

RDB快照是一次全量備份,儲存的是記憶體資料的二進位制序列化形式,儲存上非常緊湊。當進行快照持久化時,會開啟一個子程式專門負責快照持久化,子程式會擁有父程式的記憶體資料,父程式修改記憶體子程式不會反應出來,所以在快照持久化期間修改的資料不會被儲存,可能丟失資料。

三、AOF機制

全量備份總是耗時的,有時候我們提供一種更加高效的儲存方式——>AOF,工作機制很簡單,redis會將每一個收到的寫命令都通過write函式追加到檔案中。通俗的理解就是日誌記錄。

1、持久化原理

如圖所示:

每當有一個寫命令過來時,就直接儲存在我們的AOF檔案中。

2、檔案重寫原理

AOF的方式也同時帶來了另一個問題。持久化檔案會變的越來越大。為了壓縮aof的持久化檔案。redis提供了bgrewriteaof命令。將記憶體中的資料以命令的方式儲存到臨時檔案中,同時會fork出一條新程式來將檔案重寫。

重寫aof檔案的操作,並沒有讀取舊的aof檔案,而是將整個記憶體中的資料庫內容用命令的方式重寫了一個新的aof檔案,這點和快照有點類似。

3、AOF也有三種觸發機制

  • (1)每修改同步always:同步持久化 每次發生資料變更會被立即記錄到磁碟 效能較差但資料完整性比較好

  • (2)每秒同步everysec:非同步操作,每秒記錄 如果一秒內當機,有資料丟失

  • (3)不同no:從不同步

4、優點

(1)AOF可以更好的保護資料不丟失,一般AOF會每隔1秒,通過一個後臺執行緒執行一次fsync操作,最多丟失1秒鐘的資料。(2)AOF日誌檔案沒有任何磁碟定址的開銷,寫入效能非常高,檔案不容易破損。

(3)AOF日誌檔案即使過大的時候,出現後臺重寫操作,也不會影響客戶端的讀寫。

(4)AOF日誌檔案的命令通過非常可讀的方式進行記錄,這個特性非常適合做災難性的誤刪除的緊急恢復。比如某人不小心用flushall命令清空了所有資料,只要這個時候後臺rewrite還沒有發生,那麼就可以立即拷貝AOF檔案,將最後一條flushall命令給刪了,然後再將該AOF檔案放回去,就可以通過恢復機制,自動恢復所有資料

5、缺點

(1)對於同一份資料來說,AOF日誌檔案通常比RDB資料快照檔案更大

(2)AOF開啟後,支援的寫QPS會比RDB支援的寫QPS低,因為AOF一般會配置成每秒fsync一次日誌檔案,當然,每秒一次fsync,效能也還是很高的

(3)以前AOF發生過bug,就是通過AOF記錄的日誌,進行資料恢復的時候,沒有恢復一模一樣的資料出來。

四、RDB和AOF到底該如何選擇

選擇的話,兩者加一起才更好。因為兩個持久化機制你明白了,剩下的就是看自己的需求了,需求不同選擇的也不一定,但是通常都是結合使用。有一張圖可供總結:

相關文章